diff --git a/etc/accounts.yaml.sample b/etc/accounts.yaml.sample index decc659732..3dbed79e9d 100644 --- a/etc/accounts.yaml.sample +++ b/etc/accounts.yaml.sample @@ -3,7 +3,25 @@ # This is required to provide isolation between test for running in parallel # # Valid fields for credentials are defined in the descendants of -# auth.Credentials - see KeystoneV[2|3]Credentials.CONF_ATTRIBUTES +# lib.auth.Credentials - see KeystoneV[2|3]Credentials.ATTRIBUTES +# +# The fields in KeystoneV3Credentials behave as follows: +# +# tenant_[id|name] also sets project_[id|name]. +# +# project_[id|name] also sets tenant_[id|name]. +# +# Providing distinct values for both tenant_[id|name] and project_[id|name] +# will result in an InvalidCredentials exception. +# +# The value of project_domain_[id|name] is used for user_domain_[id|name] if +# the latter is not specified. +# +# The value of user_domain_[id|name] is used for project_domain_[id|name] if +# the latter is not specified. +# +# The value of domain_[id|name] is used for project_domain_[id|name] if not +# specified and user_domain_[id|name] if not specified. - username: 'user_1' tenant_name: 'test_tenant_1' diff --git a/tempest/lib/auth.py b/tempest/lib/auth.py index 2d20a0be6a..71c4f4fd05 100644 --- a/tempest/lib/auth.py +++ b/tempest/lib/auth.py @@ -622,6 +622,9 @@ class KeystoneV2Credentials(Credentials): return None not in (self.username, self.password) +COLLISIONS = [('project_name', 'tenant_name'), ('project_id', 'tenant_id')] + + class KeystoneV3Credentials(Credentials): """Credentials suitable for the Keystone Identity V3 API""" @@ -630,6 +633,16 @@ class KeystoneV3Credentials(Credentials): 'project_name', 'tenant_id', 'tenant_name', 'user_domain_id', 'user_domain_name', 'user_id'] + def _apply_credentials(self, attr): + for (key1, key2) in COLLISIONS: + val1 = attr.get(key1) + val2 = attr.get(key2) + if val1 and val2 and val1 != val2: + msg = ('Cannot have conflicting values for %s and %s' % + (key1, key2)) + raise exceptions.InvalidCredentials(msg) + super(KeystoneV3Credentials, self)._apply_credentials(attr) + def __setattr__(self, key, value): parent = super(KeystoneV3Credentials, self) # for tenant_* set both project and tenant @@ -657,8 +670,10 @@ class KeystoneV3Credentials(Credentials): parent.__setattr__('user_domain_name', value) # support domain_name coming from config if key == 'domain_name': - parent.__setattr__('user_domain_name', value) - parent.__setattr__('project_domain_name', value) + if self.user_domain_name is None: + parent.__setattr__('user_domain_name', value) + if self.project_domain_name is None: + parent.__setattr__('project_domain_name', value) # finally trigger default behaviour for all attributes parent.__setattr__(key, value) diff --git a/tempest/tests/lib/test_auth.py b/tempest/tests/lib/test_auth.py index ebcfe82883..6a01490ad1 100644 --- a/tempest/tests/lib/test_auth.py +++ b/tempest/tests/lib/test_auth.py @@ -530,3 +530,43 @@ class TestKeystoneV3AuthProvider(TestKeystoneV2AuthProvider): expected = 'http://fake_url/v3' self._test_base_url_helper(expected, filters, ('token', auth_data)) + + +class TestKeystoneV3Credentials(base.TestCase): + def testSetAttrUserDomain(self): + creds = auth.KeystoneV3Credentials() + creds.user_domain_name = 'user_domain' + creds.domain_name = 'domain' + self.assertEqual('user_domain', creds.user_domain_name) + creds = auth.KeystoneV3Credentials() + creds.domain_name = 'domain' + creds.user_domain_name = 'user_domain' + self.assertEqual('user_domain', creds.user_domain_name) + + def testSetAttrProjectDomain(self): + creds = auth.KeystoneV3Credentials() + creds.project_domain_name = 'project_domain' + creds.domain_name = 'domain' + self.assertEqual('project_domain', creds.user_domain_name) + creds = auth.KeystoneV3Credentials() + creds.domain_name = 'domain' + creds.project_domain_name = 'project_domain' + self.assertEqual('project_domain', creds.project_domain_name) + + def testProjectTenantNoCollision(self): + creds = auth.KeystoneV3Credentials(tenant_id='tenant') + self.assertEqual('tenant', creds.project_id) + creds = auth.KeystoneV3Credentials(project_id='project') + self.assertEqual('project', creds.tenant_id) + creds = auth.KeystoneV3Credentials(tenant_name='tenant') + self.assertEqual('tenant', creds.project_name) + creds = auth.KeystoneV3Credentials(project_name='project') + self.assertEqual('project', creds.tenant_name) + + def testProjectTenantCollision(self): + attrs = {'tenant_id': 'tenant', 'project_id': 'project'} + self.assertRaises( + exceptions.InvalidCredentials, auth.KeystoneV3Credentials, **attrs) + attrs = {'tenant_name': 'tenant', 'project_name': 'project'} + self.assertRaises( + exceptions.InvalidCredentials, auth.KeystoneV3Credentials, **attrs)