diff --git a/objectrocket/bases.py b/objectrocket/bases.py index e6ac661..a928369 100644 --- a/objectrocket/bases.py +++ b/objectrocket/bases.py @@ -303,3 +303,49 @@ def _register_extensions(self, namespace): ) if extmanager.extensions: extmanager.map(util.register_extension_method, base=self) + + +class InstanceAclsInterface(object): + """A mixin implementing support for the instance bound ACLs interface. + + Should only be mixed in with an Instance class. + """ + + _acls = None + + @property + def acls(self): + """The instance bound ACLs operations layer.""" + if self._acls is None: + self._acls = InstanceAcls(instance=self) + return self._acls + + +class InstanceAcls(object): + """An object implementing the ACLs interface bound to a specific instance.""" + + def __init__(self, instance): + self._instance = instance + + def all(self): + """Get all ACLs for this instance.""" + return self._instance._client.acls.all(self._instance.name) + + def create(self, cidr_mask, description, **kwargs): + """Create an ACL for this instance. + + See :py:meth:`Acls.create` for call signature. + """ + return self._instance._client.acls.create( + self._instance.name, + cidr_mask, + description, + **kwargs + ) + + def get(self, acl): + """Get the ACL specified by ID belonging to this instance. + + See :py:meth:`Acls.get` for call signature. + """ + return self._instance._client.acls.get(self._instance.name, acl) diff --git a/objectrocket/instances/elasticsearch.py b/objectrocket/instances/elasticsearch.py index 669d66f..7ead623 100644 --- a/objectrocket/instances/elasticsearch.py +++ b/objectrocket/instances/elasticsearch.py @@ -6,7 +6,7 @@ logger = logging.getLogger(__name__) -class ESInstance(bases.BaseInstance, bases.Extensible): +class ESInstance(bases.BaseInstance, bases.Extensible, bases.InstanceAclsInterface): """An ObjectRocket Elasticsearch service instance. :param dict instance_document: A dictionary representing the instance object, most likey coming diff --git a/objectrocket/instances/mongodb.py b/objectrocket/instances/mongodb.py index d320762..510663b 100644 --- a/objectrocket/instances/mongodb.py +++ b/objectrocket/instances/mongodb.py @@ -12,7 +12,7 @@ logger = logging.getLogger(__name__) -class MongodbInstance(bases.BaseInstance, bases.Extensible): +class MongodbInstance(bases.BaseInstance, bases.Extensible, bases.InstanceAclsInterface): """An ObjectRocket MongoDB service instance. :param dict instance_document: A dictionary representing the instance object, most likey coming diff --git a/objectrocket/instances/redis.py b/objectrocket/instances/redis.py index b5755e9..8a1af30 100644 --- a/objectrocket/instances/redis.py +++ b/objectrocket/instances/redis.py @@ -6,7 +6,7 @@ from objectrocket import bases -class RedisInstance(bases.BaseInstance): +class RedisInstance(bases.BaseInstance, bases.Extensible, bases.InstanceAclsInterface): """An ObjectRocket Reids service instance. :param dict instance_document: A dictionary representing the instance object. diff --git a/tests/instances/test_instances.py b/tests/instances/test_instances.py index 4285693..da05fc5 100644 --- a/tests/instances/test_instances.py +++ b/tests/instances/test_instances.py @@ -1,5 +1,8 @@ """Tests for the objectrocket.instances module.""" +import responses + from objectrocket.instances.mongodb import MongodbInstance +from objectrocket.acls import Acl ########################################## @@ -42,3 +45,59 @@ def test_concrete_instance_list_returns_expected_list(client, mongodb_sharded_do assert isinstance(output, list) assert len(output) == 1 assert output[0]._instance_document is mongodb_sharded_doc + + +####################################### +# Tests for Instances ACLs interface. # +####################################### +@responses.activate +def test_instance_acls_all_makes_expected_call(mongodb_sharded_instance): + inst = mongodb_sharded_instance + expected_url = 'http://localhost:5050/v2/instances/{}/acls/'.format(inst.name) + responses.add( + responses.GET, + expected_url, + status=200, + json={'data': []}, + content_type="application/json", + ) + + output = inst.acls.all() + + assert output == [] + + +@responses.activate +def test_instance_acls_all_returns_expected_acl_object(mongodb_sharded_instance, acl): + inst = mongodb_sharded_instance + expected_url = 'http://localhost:5050/v2/instances/{}/acls/'.format(inst.name) + responses.add( + responses.GET, + expected_url, + status=200, + json={'data': [acl._document]}, + content_type="application/json", + ) + + output = inst.acls.all() + + assert isinstance(output[0], Acl) + assert output[0].id == acl.id + + +@responses.activate +def test_instance_acls_create_makes_expected_call(mongodb_sharded_instance, acl): + inst = mongodb_sharded_instance + expected_url = 'http://localhost:5050/v2/instances/{}/acls/'.format(inst.name) + responses.add( + responses.POST, + expected_url, + status=200, + json={'data': acl._document}, + content_type="application/json", + ) + + output = inst.acls.create(cidr_mask=acl.cidr_mask, description=acl.description) + + assert isinstance(output, Acl) + assert output.id == acl.id diff --git a/tests/test_acl_sync.py b/tests/test_acl_sync.py index 81dd86a..04a54f3 100644 --- a/tests/test_acl_sync.py +++ b/tests/test_acl_sync.py @@ -20,7 +20,7 @@ def ensure_production_url(mongodb_sharded_instance, instance_acl_url): @pytest.fixture def instance_acl_url(mongodb_sharded_instance): - return "https://sjc-api.objectrocket.com/v2/instances/{}/acl_sync".format( + return "http://localhost:5050/v2/instances/{}/acl_sync".format( mongodb_sharded_instance.name )