Skip to content

Commit

Permalink
Add multiple endpoint support
Browse files Browse the repository at this point in the history
Add an Endpoint class as a part of the resource module. An Endpoint can be
optionally passed to any of of the resource objects to allow them to
access a different DCM endpoint then the one specified either by
environment variables or in configuration files as loaded by the config
class.

- Issue QSFT#210 heavily inspired this feature, thanks @thijs-creemers
- Fixes Issue QSFT#207
  • Loading branch information
igable committed Jul 13, 2015
1 parent 0aef8d1 commit 1ec1496
Show file tree
Hide file tree
Showing 37 changed files with 310 additions and 136 deletions.
8 changes: 4 additions & 4 deletions mixcoatl/admin/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class Account(Resource):
COLLECTION_NAME = 'accounts'
PRIMARY_KEY = 'account_id'

def __init__(self, account_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, account_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__account_id = account_id

@property
Expand Down Expand Up @@ -166,7 +166,7 @@ def add(self):
raise CreateAccountException(self.last_error)

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Get all accounts
>>> Account.all(detail='basic')
Expand All @@ -184,7 +184,7 @@ def all(cls, keys_only=False, **kwargs):
:returns: `list` of :class:`Account` or :attr:`account_id`
:raises: :class:`AccountException`
"""
r = Resource(cls.PATH)
r = Resource(cls.PATH,endpoint=endpoint)
params = {}

if 'detail' in kwargs:
Expand Down
10 changes: 5 additions & 5 deletions mixcoatl/admin/api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class ApiKey(Resource):
COLLECTION_NAME = 'apiKeys'
PRIMARY_KEY = 'access_key'

def __init__(self, access_key=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, access_key=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__access_key = access_key

@property
Expand Down Expand Up @@ -147,7 +147,7 @@ def generate_api_key(cls, key_name, description, expiration=None):
return a

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Get all api keys
.. note::
Expand All @@ -166,10 +166,10 @@ def all(cls, keys_only=False, **kwargs):
"""

if 'access_key' in kwargs:
r = Resource(cls.PATH + "/" + kwargs['access_key'])
r = Resource(cls.PATH + "/" + kwargs['access_key'], endpoint=endpoint)
params = {}
else:
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)

if 'detail' in kwargs:
r.request_details = kwargs['detail']
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/admin/billing_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class BillingCode(Resource):
COLLECTION_NAME = 'billingCodes'
PRIMARY_KEY = 'billing_code_id'

def __init__(self, billing_code_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, billing_code_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__billing_code_id = billing_code_id

@property
Expand Down Expand Up @@ -99,7 +99,7 @@ def soft_quota(self, s):
self.__soft_quota = s

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Get all visible billing codes
.. note::
Expand All @@ -113,7 +113,7 @@ def all(cls, keys_only=False, **kwargs):
:returns: `list` - of :class:`BillingCode` or :attr:`billing_code_id`
:raises: :class:`BillingCodeException`
"""
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)
params = {}

if 'details' in kwargs:
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/admin/customer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class Customer(Resource):
COLLECTION_NAME = 'customers'
PRIMARY_KEY = 'customer_id'

def __init__(self, role_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, role_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__customer_id = customer_id

@property
Expand All @@ -29,9 +29,9 @@ def customer_id(self):
return self.__customer_id

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Get all customers"""
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)
params = {}

if 'detail' in kwargs:
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/admin/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class Group(Resource):
COLLECTION_NAME = 'groups'
PRIMARY_KEY = 'group_id'

def __init__(self, group_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, group_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__group_id = group_id

@property
Expand Down Expand Up @@ -90,7 +90,7 @@ def role_assignments(self):
return self.__role_assignments

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Get all groups
.. note::
Expand All @@ -106,7 +106,7 @@ def all(cls, keys_only=False, **kwargs):
:returns: `list` - List of :class:`Group` or :attr:`group_id`
:raises: :class:`GroupException`
"""
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)
params = {}

if 'detail' in kwargs:
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/admin/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class Job(Resource):
COLLECTION_NAME = 'jobs'
PRIMARY_KEY = 'job_id'

def __init__(self, job_id=None, **kwargs):
Resource.__init__(self)
def __init__(self, job_id=None, endpoint=None, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__job_id = job_id

@property
Expand Down Expand Up @@ -59,14 +59,14 @@ def job_message(self):
return self.__job_message

@classmethod
def all(cls, keys_only=False):
def all(cls, keys_only=False, endpoint=None):
"""Get all jobs
:param keys_only: Only return :attr:`job_id` instead of :class:`Job`
:type keys_only: bool.
:returns: `list` of :class:`Job` or :attr:`job_id`
:raises: :class:`JobException`
"""
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)
x = r.get()
if r.last_error is None:
if keys_only is True:
Expand Down
6 changes: 3 additions & 3 deletions mixcoatl/admin/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class Role(Resource):
COLLECTION_NAME = 'roles'
PRIMARY_KEY = 'role_id'

def __init__(self, role_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, role_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__role_id = role_id

@property
Expand Down Expand Up @@ -92,7 +92,7 @@ def create(self):
raise RoleCreationException(self.last_error)

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Get all roles
.. note::
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/admin/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class User(Resource):
COLLECTION_NAME = 'users'
PRIMARY_KEY = 'user_id'

def __init__(self, user_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, user_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__user_id = user_id

@property
Expand Down Expand Up @@ -252,7 +252,7 @@ def create(self):
raise UserCreationException(self.last_error)

@classmethod
def all(cls, keys_only=False, **kwargs):
def all(cls, keys_only=False, endpoint=None, **kwargs):
"""Return all users
.. note::
Expand All @@ -266,7 +266,7 @@ def all(cls, keys_only=False, **kwargs):
:returns: `list` of :class:`User` or :attr:`user_id`
:raises: :class:`UserException`
"""
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)
if 'detail' in kwargs:
r.request_details = kwargs['detail']
else:
Expand Down
4 changes: 2 additions & 2 deletions mixcoatl/analytics/server_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def interval_in_minutes(self):
return self.__interval_in_minutes

@classmethod
def all(cls, server_id, keys_only=False, **kwargs):
def all(cls, server_id, keys_only=False, endpoint=None, **kwargs):
"""Get all analytics for `server_id`
:param server_id: The server represented in the analytics
Expand All @@ -80,7 +80,7 @@ def all(cls, server_id, keys_only=False, **kwargs):
:param period_end: int.
:returns: :class:`ServerAnalytics` or `list` of :attr:`data_points`
"""
r = Resource(cls.PATH)
r = Resource(cls.PATH, endpoint=endpoint)
params = {}
if 'detail' in kwargs:
r.request_details = kwargs['detail']
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/analytics/tier_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class TierAnalytics(Resource):
COLLECTION_NAME = 'analytics'
PRIMARY_KEY = 'tier_id'

def __init__(self, tier_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, tier_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__tier_id = tier_id

@property
Expand All @@ -32,8 +32,8 @@ def interval_in_minutes(self):
return self.__interval_in_minutes

@classmethod
def all(cls, tier_id, **kwargs):
r = Resource(cls.PATH+'/'+str(tier_id))
def all(cls, tier_id, endpoint=None, **kwargs):
r = Resource(cls.PATH+'/'+str(tier_id), endpoint=endpoint)
if 'details' in kwargs:
r.request_details = kwargs['details']
else:
Expand Down
20 changes: 15 additions & 5 deletions mixcoatl/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,36 @@
from mixcoatl.settings.load_settings import settings


def get_sig(http_method, path):
def get_sig(http_method, path, endpoint=None):
"""Return a signature valid for use in making DCM API calls
:param http_method: The `http_method` used to make the API call
:param path: The `path` used in the API call
"""

if endpoint:
access_key = endpoint.access_key
secret_key = endpoint.secret_key
basepath = endpoint.basepath
else:
access_key = settings.access_key
secret_key = settings.secret_key
basepath = settings.basepath

timestamp = int(round(time.time() * 1000))
signpath = settings.basepath + '/' + path
signpath = basepath + '/' + path
parts = []
parts.append(settings.access_key)
parts.append(access_key)
parts.append(http_method)
parts.append(signpath)
parts.append(timestamp)
parts.append(settings.user_agent)
# pylint: disable-msg=E1101
dm = hashlib.sha256
to_sign = ':'.join([str(x) for x in parts])
d = hmac.new(settings.secret_key, msg=to_sign, digestmod=dm).digest()
d = hmac.new(secret_key, msg=to_sign, digestmod=dm).digest()
b64auth = base64.b64encode(d).decode()
return {'timestamp': timestamp,
'signature': b64auth,
'access_key': settings.access_key,
'access_key': access_key,
'ua': settings.user_agent}
8 changes: 4 additions & 4 deletions mixcoatl/automation/configuration_management_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class ConfigurationManagementAccount(Resource):
COLLECTION_NAME = 'cmAccounts'
PRIMARY_KEY = 'cm_account_id'

def __init__(self, cm_account_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, cm_account_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__cm_account_id = cm_account_id

@property
Expand Down Expand Up @@ -77,8 +77,8 @@ def owning_user(self):
return self.__owning_user

@classmethod
def all(cls, **kwargs):
r = Resource(cls.PATH)
def all(cls, endpoint=None, **kwargs):
r = Resource(cls.PATH, endpoint=endpoint)
if 'details' in kwargs:
r.request_details = kwargs['details']
else:
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/automation/configuration_management_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class ConfigurationManagementService(Resource):
COLLECTION_NAME = 'cmServices'
PRIMARY_KEY = 'cm_system_id'

def __init__(self, cm_account_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, cm_account_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)

@lazy_property
def cm_system(self):
Expand Down Expand Up @@ -91,8 +91,8 @@ def create(self):
raise CMCreationException(self.last_error)

@classmethod
def all(cls, **kwargs):
r = Resource(cls.PATH)
def all(cls, endpoint=None, **kwargs):
r = Resource(cls.PATH, endpoint=endpoint)

if 'details' in kwargs:
r.request_details = kwargs['details']
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/automation/configuration_management_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ class ConfigurationManagementSystem(Resource):
COLLECTION_NAME = 'cmSystems'
PRIMARY_KEY = 'cm_system_id'

def __init__(self, cm_account_id=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, cm_account_id=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)

@classmethod
def all(cls, **kwargs):
r = Resource(cls.PATH)
def all(cls, endpoint=None, **kwargs):
r = Resource(cls.PATH, endpoint=endpoint)

if 'details' in kwargs:
r.request_details = kwargs['details']
Expand Down
8 changes: 4 additions & 4 deletions mixcoatl/automation/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ class Environment(Resource):
COLLECTION_NAME = 'environments'
PRIMARY_KEY = 'environmentId'

def __init__(self, environmentId=None, *args, **kwargs):
Resource.__init__(self)
def __init__(self, environmentId=None, endpoint=None, *args, **kwargs):
Resource.__init__(self, endpoint=endpoint)
self.__environmentId = environmentId

@classmethod
def all(cls, cmAccountId, **kwargs):
r = Resource(cls.PATH)
def all(cls, cmAccountId, endpoint=None, **kwargs):
r = Resource(cls.PATH, endpoint=endpoint)

if 'detail' in kwargs:
r.request_details = kwargs['detail']
Expand Down
Loading

0 comments on commit 1ec1496

Please sign in to comment.