requests module plugged
What is done: * urllib2 code changed to corresponding from requests * error handling for APIclient updated in order to exploit requests exceptions classes. Partially implements: blueprint refactoring-for-fuelclient Change-Id: I7f1c0b390828f4a77daeaca370cfb16a5df3839d
This commit is contained in:
@@ -14,8 +14,8 @@
|
||||
|
||||
from functools import wraps
|
||||
from keystoneclient.exceptions import Unauthorized
|
||||
import requests
|
||||
import sys
|
||||
import urllib2
|
||||
|
||||
|
||||
def exit_with_error(message):
|
||||
@@ -67,40 +67,36 @@ class ParserException(FuelClientException):
|
||||
"""
|
||||
|
||||
|
||||
def handle_exceptions(exc):
|
||||
"""handle_exceptions - exception handling manager.
|
||||
"""
|
||||
if isinstance(exc, urllib2.HTTPError):
|
||||
error_body = exc.read()
|
||||
exit_with_error("{0} {1}".format(
|
||||
exc,
|
||||
"({0})".format(error_body or "")
|
||||
))
|
||||
elif isinstance(exc, urllib2.URLError):
|
||||
exit_with_error("""
|
||||
Can't connect to Nailgun server!
|
||||
Please modify "SERVER_ADDRESS" and "LISTEN_PORT"
|
||||
in the file /etc/fuel/client/config.yaml""")
|
||||
elif isinstance(exc, Unauthorized):
|
||||
exit_with_error("""
|
||||
Unauthorized: need authentication!
|
||||
Please provide user and password via client --os-username --os-password
|
||||
or modify "KEYSTONE_USER" and "KEYSTONE_PASS" in
|
||||
/etc/fuel/client/config.yaml""")
|
||||
elif isinstance(exc, FuelClientException):
|
||||
exit_with_error(exc.message)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def exceptions_decorator(func):
|
||||
"""exceptions_decorator - is decorator which intercepts exceptions and
|
||||
redirects them to handle_exceptions.
|
||||
"""Handles HTTP errors and expected exceptions that may occur
|
||||
in methods of APIClient class
|
||||
"""
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as exc:
|
||||
handle_exceptions(exc)
|
||||
|
||||
# when server returns to us bad request check that
|
||||
# and print meaningful reason
|
||||
except requests.HTTPError as exc:
|
||||
error_body = exc.response.text
|
||||
exit_with_error("{0} ({1})".format(exc, error_body))
|
||||
except requests.ConnectionError:
|
||||
exit_with_error("""
|
||||
Can't connect to Nailgun server!
|
||||
Please modify "SERVER_ADDRESS" and "LISTEN_PORT"
|
||||
in the file /etc/fuel/client/config.yaml""")
|
||||
except Unauthorized:
|
||||
exit_with_error("""
|
||||
Unauthorized: need authentication!
|
||||
Please provide user and password via client
|
||||
--os-username --os-password
|
||||
or modify "KEYSTONE_USER" and "KEYSTONE_PASS" in
|
||||
/etc/fuel/client/config.yaml""")
|
||||
except FuelClientException as exc:
|
||||
exit_with_error(exc.message)
|
||||
# not all responses return data
|
||||
except ValueError:
|
||||
return {}
|
||||
|
||||
return wrapper
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import urllib2
|
||||
import requests
|
||||
|
||||
import yaml
|
||||
|
||||
@@ -71,11 +71,14 @@ class Client(object):
|
||||
return ''
|
||||
|
||||
@property
|
||||
@exceptions_decorator
|
||||
def auth_required(self):
|
||||
if self._auth_required is None:
|
||||
request = urllib2.urlopen(''.join([self.api_root, 'version']))
|
||||
self._auth_required = json.loads(
|
||||
request.read()).get('auth_required', False)
|
||||
url = self.api_root + 'version'
|
||||
resp = requests.get(url)
|
||||
resp.raise_for_status()
|
||||
|
||||
self._auth_required = resp.json().get('auth_required', False)
|
||||
return self._auth_required
|
||||
|
||||
@property
|
||||
@@ -107,37 +110,41 @@ class Client(object):
|
||||
if self.debug:
|
||||
print(message)
|
||||
|
||||
@exceptions_decorator
|
||||
def delete_request(self, api):
|
||||
"""Make DELETE request to specific API with some data
|
||||
"""
|
||||
url = self.api_root + api
|
||||
self.print_debug(
|
||||
"DELETE {0}".format(self.api_root + api)
|
||||
)
|
||||
opener = urllib2.build_opener(urllib2.HTTPHandler)
|
||||
request = urllib2.Request(self.api_root + api)
|
||||
request.add_header('Content-Type', 'application/json')
|
||||
request.add_header('X-Auth-Token', self.auth_token)
|
||||
request.get_method = lambda: 'DELETE'
|
||||
opener.open(request)
|
||||
return {}
|
||||
|
||||
headers = {'content-type': 'application/json',
|
||||
'x-auth-token': self.auth_token}
|
||||
resp = requests.delete(url, headers=headers)
|
||||
resp.raise_for_status()
|
||||
|
||||
return resp.json()
|
||||
|
||||
@exceptions_decorator
|
||||
def put_request(self, api, data):
|
||||
"""Make PUT request to specific API with some data
|
||||
"""
|
||||
url = self.api_root + api
|
||||
data_json = json.dumps(data)
|
||||
self.print_debug(
|
||||
"PUT {0} data={1}"
|
||||
.format(self.api_root + api, data_json)
|
||||
)
|
||||
opener = urllib2.build_opener(urllib2.HTTPHandler)
|
||||
request = urllib2.Request(self.api_root + api, data=data_json)
|
||||
request.add_header('Content-Type', 'application/json')
|
||||
request.add_header('X-Auth-Token', self.auth_token)
|
||||
request.get_method = lambda: 'PUT'
|
||||
return json.loads(
|
||||
opener.open(request).read()
|
||||
)
|
||||
|
||||
headers = {'content-type': 'application/json',
|
||||
'x-auth-token': self.auth_token}
|
||||
resp = requests.put(url, data=data_json, headers=headers)
|
||||
resp.raise_for_status()
|
||||
|
||||
return resp.json()
|
||||
|
||||
@exceptions_decorator
|
||||
def get_request(self, api, ostf=False):
|
||||
"""Make GET request to specific API
|
||||
"""
|
||||
@@ -146,13 +153,14 @@ class Client(object):
|
||||
"GET {0}"
|
||||
.format(url)
|
||||
)
|
||||
opener = urllib2.build_opener(urllib2.HTTPHandler)
|
||||
request = urllib2.Request(url)
|
||||
request.add_header('X-Auth-Token', self.auth_token)
|
||||
return json.loads(
|
||||
opener.open(request).read()
|
||||
)
|
||||
|
||||
headers = {'x-auth-token': self.auth_token}
|
||||
resp = requests.get(url, headers=headers)
|
||||
resp.raise_for_status()
|
||||
|
||||
return resp.json()
|
||||
|
||||
@exceptions_decorator
|
||||
def post_request(self, api, data, ostf=False):
|
||||
"""Make POST request to specific API with some data
|
||||
"""
|
||||
@@ -162,22 +170,13 @@ class Client(object):
|
||||
"POST {0} data={1}"
|
||||
.format(url, data_json)
|
||||
)
|
||||
request = urllib2.Request(
|
||||
url=url,
|
||||
data=data_json,
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
request.add_header('X-Auth-Token', self.auth_token)
|
||||
try:
|
||||
response = json.loads(
|
||||
urllib2.urlopen(request)
|
||||
.read()
|
||||
)
|
||||
except ValueError:
|
||||
response = {}
|
||||
return response
|
||||
|
||||
headers = {'content-type': 'application/json',
|
||||
'x-auth-token': self.auth_token}
|
||||
resp = requests.post(url, data=data_json, headers=headers)
|
||||
resp.raise_for_status()
|
||||
|
||||
return resp.json()
|
||||
|
||||
@exceptions_decorator
|
||||
def get_fuel_version(self):
|
||||
|
||||
@@ -4,6 +4,7 @@ Mako==0.9.1
|
||||
MarkupSafe==0.18
|
||||
Paste==1.7.5.1
|
||||
PyYAML==3.10
|
||||
requests>=1.2.3
|
||||
SQLAlchemy==0.7.9
|
||||
Shotgun==0.1.0
|
||||
alembic==0.6.2
|
||||
|
||||
@@ -102,11 +102,13 @@ class TestHandlers(BaseTestCase):
|
||||
def test_wrong_credentials(self):
|
||||
result = self.run_cli_command("--os-username=a --os-password=a node",
|
||||
check_errors=True)
|
||||
self.assertEqual(result.stderr,
|
||||
'\n Unauthorized: need authentication!\n'
|
||||
' Please provide user and password via client --os-username '
|
||||
'--os-password\n or modify "KEYSTONE_USER" and "KEYSTONE_PASS" '
|
||||
'in\n /etc/fuel/client/config.yaml\n')
|
||||
must_be = ('\n Unauthorized: need authentication!\n '
|
||||
' Please provide user and password via client\n '
|
||||
' --os-username --os-password\n or modify '
|
||||
'"KEYSTONE_USER" and "KEYSTONE_PASS" in\n '
|
||||
'/etc/fuel/client/config.yaml\n'
|
||||
)
|
||||
self.assertEqual(result.stderr, must_be)
|
||||
|
||||
def test_destroy_node(self):
|
||||
self.load_data_to_nailgun_server()
|
||||
@@ -117,9 +119,9 @@ class TestHandlers(BaseTestCase):
|
||||
msg = ("Nodes with id [1] has been deleted from fuel db.\n"
|
||||
"You should still delete node from cobbler\n")
|
||||
self.check_for_stdout(
|
||||
"node --node 1 --delete-from-db",
|
||||
msg
|
||||
)
|
||||
"node --node 1 --delete-from-db",
|
||||
msg
|
||||
)
|
||||
|
||||
def test_for_examples_in_action_help(self):
|
||||
actions = (
|
||||
|
||||
Reference in New Issue
Block a user