Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions SoftLayer/API.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@
API_BASE_URL = API_PUBLIC_ENDPOINT


class AuthenticationBase(object):
def get_headers(self):
raise NotImplementedError


class BasicAuthentication(AuthenticationBase):
def __init__(self, username, api_key):
self.username = username
self.api_key = api_key

def get_headers(self):
return {
'authenticate': {
'username': self.username,
'apiKey': self.api_key,
}
}

def __repr__(self):
return "<BasicAuthentication: %s>" % (self.username)


class Client(object):
""" A SoftLayer API client.

Expand All @@ -33,6 +55,8 @@ class Client(object):
network.
:param integer timeout: timeout for API requests
:param boolean verbose: prints details about every HTTP request if true
:param auth: an object which responds to get_headers() to be inserted into
the xml-rpc headers. Example: `BasicAuthentication`

Usage:

Expand All @@ -46,16 +70,19 @@ class Client(object):
_prefix = "SoftLayer_"

def __init__(self, service_name=None, id=None, username=None, api_key=None,
endpoint_url=None, timeout=None, verbose=False):
endpoint_url=None, timeout=None, verbose=False, auth=None):
self._service_name = service_name
self.verbose = verbose
self._headers = {}
self._raw_headers = {}

self.username = username or API_USERNAME or \
os.environ.get('SL_USERNAME') or ''
self.api_key = api_key or API_KEY or os.environ.get('SL_API_KEY') or ''
self.set_authentication(self.username, self.api_key)
self.auth = auth
if self.auth is None:
username = username or API_USERNAME or \
os.environ.get('SL_USERNAME') or ''
api_key = api_key or API_KEY or os.environ.get('SL_API_KEY') or ''
self.auth = BasicAuthentication(username, api_key)
self.set_authentication(username, api_key)

if id is not None:
self.set_init_parameter(int(id))
Expand Down Expand Up @@ -226,11 +253,7 @@ def call(self, service, method, *args, **kwargs):
offset = kwargs.get('offset', 0)

if headers is None:
headers = {
'authenticate': {
'username': self.username,
'apiKey': self.api_key,
}}
headers = self.auth.get_headers()

http_headers = {
'User-Agent': USER_AGENT,
Expand Down Expand Up @@ -366,8 +389,8 @@ def call_handler(*args, **kwargs):
return call_handler

def __repr__(self):
return "<Client: endpoint=%s, user=%s>" \
% (self._endpoint_url, self.username)
return "<Client: endpoint=%s, user=%r>" \
% (self._endpoint_url, self.auth)

__str__ = __repr__

Expand Down
7 changes: 4 additions & 3 deletions SoftLayer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"""
from SoftLayer.consts import VERSION

from API import Client, API_PUBLIC_ENDPOINT, API_PRIVATE_ENDPOINT
from API import (
Client, BasicAuthentication, API_PUBLIC_ENDPOINT, API_PRIVATE_ENDPOINT)
from DNS import DNSManager
from CCI import CCIManager
from metadata import MetadataManager
Expand All @@ -27,6 +28,6 @@
__author__ = 'SoftLayer Technologies, Inc.'
__license__ = 'The BSD License'
__copyright__ = 'Copyright 2013 SoftLayer Technologies, Inc.'
__all__ = ['Client', 'SoftLayerError', 'SoftLayerAPIError',
'API_PUBLIC_ENDPOINT', 'API_PRIVATE_ENDPOINT',
__all__ = ['Client', 'BasicAuthentication', 'SoftLayerError',
'SoftLayerAPIError', 'API_PUBLIC_ENDPOINT', 'API_PRIVATE_ENDPOINT',
'DNSManager', 'CCIManager', 'MetadataManager']
28 changes: 28 additions & 0 deletions SoftLayer/tests/API/client_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,31 @@ def test_iter_call(self, _call):
AttributeError,
lambda: list(self.client.iter_call(
'SERVICE', 'METHOD', iter=True, chunk=0)))


class TestAuthenticationBase(unittest.TestCase):
def test_get_headers(self):
auth = SoftLayer.API.AuthenticationBase()
self.assertRaises(NotImplementedError, auth.get_headers)


class TestBasicAuthentication(unittest.TestCase):
def setUp(self):
self.auth = SoftLayer.BasicAuthentication('USERNAME', 'APIKEY')

def test_attribs(self):
self.assertEquals(self.auth.username, 'USERNAME')
self.assertEquals(self.auth.api_key, 'APIKEY')

def test_get_headers(self):
self.assertEquals(self.auth.get_headers(), {
'authenticate': {
'username': 'USERNAME',
'apiKey': 'APIKEY',
}
})

def test_repr(self):
s = repr(self.auth)
self.assertIn('BasicAuthentication', s)
self.assertIn('USERNAME', s)