From f9fbca21aeed580e76899ba4c1c8a00ed94860bc Mon Sep 17 00:00:00 2001 From: Charles V Bock Date: Thu, 1 Aug 2013 17:11:50 -0700 Subject: [PATCH] Adds support for passing extra tenant attributes to keystone Patch adds simple kwargs parsing to tenant update and create methods allowing users to exercise the extras functionality of keystone. As-per keystone data model docs: http://docs.openstack.org/developer/keystone/architecture.html#data-model Change-Id: I1c375c70a0ab4519626d2238d65fa0695f953dc5 Fixes: bug #1180317 --- keystoneclient/v2_0/tenants.py | 15 ++++++++++++-- keystoneclient/v3/projects.py | 10 +++++---- tests/v2_0/test_tenants.py | 37 +++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/keystoneclient/v2_0/tenants.py b/keystoneclient/v2_0/tenants.py index 531e8fc84..cecec830e 100644 --- a/keystoneclient/v2_0/tenants.py +++ b/keystoneclient/v2_0/tenants.py @@ -74,7 +74,7 @@ class TenantManager(base.ManagerWithFind): def get(self, tenant_id): return self._get("/tenants/%s" % tenant_id, "tenant") - def create(self, tenant_name, description=None, enabled=True): + def create(self, tenant_name, description=None, enabled=True, **kwargs): """ Create a new tenant. @@ -83,6 +83,11 @@ class TenantManager(base.ManagerWithFind): "description": description, "enabled": enabled}} + #Allow Extras Passthru and ensure we don't clobber primary arguments. + for k, v in kwargs.iteritems(): + if k not in params['tenant']: + params['tenant'][k] = v + return self._create('/tenants', params, "tenant") def list(self, limit=None, marker=None): @@ -119,7 +124,7 @@ class TenantManager(base.ManagerWithFind): return tenant_list def update(self, tenant_id, tenant_name=None, description=None, - enabled=None): + enabled=None, **kwargs): """ Update a tenant with a new name and description. """ @@ -130,6 +135,12 @@ class TenantManager(base.ManagerWithFind): body['tenant']['enabled'] = enabled if description is not None: body['tenant']['description'] = description + + #Allow Extras Passthru and ensure we don't clobber primary arguments. + for k, v in kwargs.iteritems(): + if k not in body['tenant']: + body['tenant'][k] = v + # Keystone's API uses a POST rather than a PUT here. return self._create("/tenants/%s" % tenant_id, body, "tenant") diff --git a/keystoneclient/v3/projects.py b/keystoneclient/v3/projects.py index cb08061d1..25df9a622 100644 --- a/keystoneclient/v3/projects.py +++ b/keystoneclient/v3/projects.py @@ -51,12 +51,13 @@ class ProjectManager(base.CrudManager): collection_key = 'projects' key = 'project' - def create(self, name, domain, description=None, enabled=True): + def create(self, name, domain, description=None, enabled=True, **kwargs): return super(ProjectManager, self).create( domain_id=base.getid(domain), name=name, description=description, - enabled=enabled) + enabled=enabled, + **kwargs) def list(self, domain=None, user=None, **kwargs): """List projects. @@ -78,13 +79,14 @@ class ProjectManager(base.CrudManager): project_id=base.getid(project)) def update(self, project, name=None, domain=None, description=None, - enabled=None): + enabled=None, **kwargs): return super(ProjectManager, self).update( project_id=base.getid(project), domain_id=base.getid(domain), name=name, description=description, - enabled=enabled) + enabled=enabled, + **kwargs) def delete(self, project): return super(ProjectManager, self).delete( diff --git a/tests/v2_0/test_tenants.py b/tests/v2_0/test_tenants.py index a5bca526b..bf87e3509 100644 --- a/tests/v2_0/test_tenants.py +++ b/tests/v2_0/test_tenants.py @@ -41,6 +41,13 @@ class TenantTests(utils.TestCase): "description": "None", "name": "admin", "id": 1, + }, + { + "extravalue01": "metadata01", + "enabled": True, + "description": "For testing extras", + "name": "test_extras", + "id": 4, } ], "links": [], @@ -52,7 +59,8 @@ class TenantTests(utils.TestCase): "tenant": { "name": "tenantX", "description": "Like tenant 9, but better.", - "enabled": True + "enabled": True, + "extravalue01": "metadata01", }, } resp_body = { @@ -61,6 +69,7 @@ class TenantTests(utils.TestCase): "enabled": True, "id": 4, "description": "Like tenant 9, but better.", + "extravalue01": "metadata01", } } resp = utils.TestResponse({ @@ -75,14 +84,17 @@ class TenantTests(utils.TestCase): urlparse.urljoin(self.TEST_URL, 'v2.0/tenants'), **kwargs).AndReturn((resp)) self.mox.ReplayAll() - - tenant = self.client.tenants.create(req_body['tenant']['name'], - req_body['tenant']['description'], - req_body['tenant']['enabled']) + tenant = self.client.tenants.create( + req_body['tenant']['name'], + req_body['tenant']['description'], + req_body['tenant']['enabled'], + extravalue01=req_body['tenant']['extravalue01'], + name="dont overwrite priors") self.assertTrue(isinstance(tenant, tenants.Tenant)) self.assertEqual(tenant.id, 4) self.assertEqual(tenant.name, "tenantX") self.assertEqual(tenant.description, "Like tenant 9, but better.") + self.assertEqual(tenant.extravalue01, "metadata01") def test_duplicate_create(self): req_body = { @@ -228,6 +240,8 @@ class TenantTests(utils.TestCase): "name": "tenantX", "description": "I changed you!", "enabled": False, + "extravalue01": "metadataChanged", + #"extraname": "dontoverwrite!", }, } resp_body = { @@ -236,6 +250,7 @@ class TenantTests(utils.TestCase): "enabled": False, "id": 4, "description": "I changed you!", + "extravalue01": "metadataChanged", }, } resp = utils.TestResponse({ @@ -252,15 +267,19 @@ class TenantTests(utils.TestCase): **kwargs).AndReturn((resp)) self.mox.ReplayAll() - tenant = self.client.tenants.update(req_body['tenant']['id'], - req_body['tenant']['name'], - req_body['tenant']['description'], - req_body['tenant']['enabled']) + tenant = self.client.tenants.update( + req_body['tenant']['id'], + req_body['tenant']['name'], + req_body['tenant']['description'], + req_body['tenant']['enabled'], + extravalue01=req_body['tenant']['extravalue01'], + name="dont overwrite priors") self.assertTrue(isinstance(tenant, tenants.Tenant)) self.assertEqual(tenant.id, 4) self.assertEqual(tenant.name, "tenantX") self.assertEqual(tenant.description, "I changed you!") self.assertFalse(tenant.enabled) + self.assertEqual(tenant.extravalue01, "metadataChanged") def test_update_empty_description(self): req_body = {