From 133b321125eeb4c22b2963dbd112a074cfeb6ab1 Mon Sep 17 00:00:00 2001 From: spisarski Date: Fri, 17 Nov 2017 09:25:33 -0700 Subject: Refactoring of UserSettings to extend UserConfig UserSettings and keystone_utils have a runtime cyclical dependency. This patch reduces this dependency and deprecates the UserSettings class. JIRA: SNAPS-226 Change-Id: Ifcc2a029463780e963b1afcf1de31baf9edded40 Signed-off-by: spisarski --- docs/how-to-use/LibraryUsage.rst | 7 +- docs/how-to-use/UnitTests.rst | 8 ++- examples/launch.py | 5 +- snaps/config/tests/user_tests.py | 84 ++++++++++++++++++++++ snaps/config/user.py | 59 +++++++++++++++ snaps/openstack/create_user.py | 49 +++---------- snaps/openstack/tests/create_project_tests.py | 12 ++-- snaps/openstack/tests/create_user_tests.py | 3 +- snaps/openstack/tests/os_source_file_test.py | 4 +- .../openstack/utils/tests/keystone_utils_tests.py | 6 +- snaps/test_suite_builder.py | 3 + 11 files changed, 184 insertions(+), 56 deletions(-) create mode 100644 snaps/config/tests/user_tests.py create mode 100644 snaps/config/user.py diff --git a/docs/how-to-use/LibraryUsage.rst b/docs/how-to-use/LibraryUsage.rst index ae28212..b5cff12 100644 --- a/docs/how-to-use/LibraryUsage.rst +++ b/docs/how-to-use/LibraryUsage.rst @@ -79,7 +79,7 @@ Create User ----------- - User - snaps.openstack.create\_user.OpenStackUser - - snaps.openstack.create\_user.UserSettings + - snaps.openstack.user.UserConfig - name - the username (required) - password - the user's password (required) @@ -94,8 +94,9 @@ Create User .. code:: python - from snaps.openstack.create_user import UserSettings, OpenStackUser - user_settings = UserSettings(name='username', password='password') + from snaps.config.user import UserConfig + from snaps.openstack.create_user import OpenStackUser + user_settings = UserConfig(name='username', password='password') user_creator = OpenStackUser(os_creds, user_settings) user_creator.create() diff --git a/docs/how-to-use/UnitTests.rst b/docs/how-to-use/UnitTests.rst index 214e2b8..e45a114 100644 --- a/docs/how-to-use/UnitTests.rst +++ b/docs/how-to-use/UnitTests.rst @@ -114,11 +114,17 @@ KeypairDomainObjectTests Ensures that all required members are included when constructing a Keypair domain object +UserConfigUnitTests +------------------- + +Ensures that all required members are included when constructing a +UserConfig object + UserSettingsUnitTests --------------------- Ensures that all required members are included when constructing a -UserSettings object +deprecated UserSettings object UserDomainObjectTests --------------------- diff --git a/examples/launch.py b/examples/launch.py index d1129b0..0ed6456 100644 --- a/examples/launch.py +++ b/examples/launch.py @@ -30,6 +30,7 @@ from snaps.config.flavor import FlavorConfig from snaps.config.image import ImageConfig from snaps.config.keypair import KeypairConfig from snaps.config.project import ProjectConfig +from snaps.config.user import UserConfig from snaps.openstack.create_flavor import OpenStackFlavor from snaps.openstack.create_image import OpenStackImage from snaps.openstack.create_instance import VmInstanceSettings @@ -41,7 +42,7 @@ from snaps.openstack.create_qos import QoSSettings, OpenStackQoS from snaps.openstack.create_router import RouterSettings, OpenStackRouter from snaps.openstack.create_security_group import ( OpenStackSecurityGroup, SecurityGroupSettings) -from snaps.openstack.create_user import OpenStackUser, UserSettings +from snaps.openstack.create_user import OpenStackUser from snaps.openstack.create_volume import OpenStackVolume, VolumeSettings from snaps.openstack.create_volume_type import ( OpenStackVolumeType, VolumeTypeSettings) @@ -622,7 +623,7 @@ def main(arguments): # Create users users_dict = __create_instances( - os_creds_dict, OpenStackUser, UserSettings, + os_creds_dict, OpenStackUser, UserConfig, os_config.get('users'), 'user', clean) creators.append(users_dict) diff --git a/snaps/config/tests/user_tests.py b/snaps/config/tests/user_tests.py new file mode 100644 index 0000000..d3d8feb --- /dev/null +++ b/snaps/config/tests/user_tests.py @@ -0,0 +1,84 @@ +# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs") +# and others. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest + +from snaps.config.user import UserConfig + + +class UserConfigUnitTests(unittest.TestCase): + """ + Tests the construction of the UserConfig class + """ + + def test_no_params(self): + with self.assertRaises(Exception): + UserConfig() + + def test_empty_config(self): + with self.assertRaises(Exception): + UserConfig(**dict()) + + def test_name_only(self): + with self.assertRaises(Exception): + UserConfig(name='foo') + + def test_config_with_name_only(self): + with self.assertRaises(Exception): + UserConfig(**{'name': 'foo'}) + + def test_name_pass_enabled_str(self): + with self.assertRaises(Exception): + UserConfig(name='foo', password='bar', enabled='true') + + def test_config_with_name_pass_enabled_str(self): + with self.assertRaises(Exception): + UserConfig( + **{'name': 'foo', 'password': 'bar', 'enabled': 'true'}) + + def test_name_pass_only(self): + settings = UserConfig(name='foo', password='bar') + self.assertEqual('foo', settings.name) + self.assertEqual('bar', settings.password) + self.assertIsNone(settings.project_name) + self.assertIsNone(settings.email) + self.assertTrue(settings.enabled) + + def test_config_with_name_pass_only(self): + settings = UserConfig(**{'name': 'foo', 'password': 'bar'}) + self.assertEqual('foo', settings.name) + self.assertEqual('bar', settings.password) + self.assertIsNone(settings.project_name) + self.assertIsNone(settings.email) + self.assertTrue(settings.enabled) + + def test_all(self): + settings = UserConfig( + name='foo', password='bar', project_name='proj-foo', + email='foo@bar.com', enabled=False) + self.assertEqual('foo', settings.name) + self.assertEqual('bar', settings.password) + self.assertEqual('proj-foo', settings.project_name) + self.assertEqual('foo@bar.com', settings.email) + self.assertFalse(settings.enabled) + + def test_config_all(self): + settings = UserConfig( + **{'name': 'foo', 'password': 'bar', 'project_name': 'proj-foo', + 'email': 'foo@bar.com', 'enabled': False}) + self.assertEqual('foo', settings.name) + self.assertEqual('bar', settings.password) + self.assertEqual('proj-foo', settings.project_name) + self.assertEqual('foo@bar.com', settings.email) + self.assertFalse(settings.enabled) diff --git a/snaps/config/user.py b/snaps/config/user.py new file mode 100644 index 0000000..fcc8fac --- /dev/null +++ b/snaps/config/user.py @@ -0,0 +1,59 @@ +# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs") +# and others. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class UserConfig(object): + """ + Class for holding user configurations + """ + def __init__(self, **kwargs): + + """ + Constructor + :param name: the user's name (required) + :param password: the user's password (required) + :param project_name: the user's primary project name (optional) + :param domain_name: the user's domain name (default='Default'). For v3 + APIs + :param email: the user's email address (optional) + :param enabled: denotes whether or not the user is enabled + (default True) + :param roles: dict where key is the role's name and value is the name + of the project to associate with the role (optional) + """ + + self.name = kwargs.get('name') + self.password = kwargs.get('password') + self.project_name = kwargs.get('project_name') + self.email = kwargs.get('email') + self.domain_name = kwargs.get('domain_name', 'Default') + self.enabled = kwargs.get('enabled', True) + self.roles = kwargs.get('roles', dict()) + + if not self.name or not self.password: + raise UserConfigException( + 'The attributes name and password are required for ' + 'UserConfig') + + if not isinstance(self.enabled, bool): + raise UserConfigException( + 'The attribute enabled must be of type boolean') + + +class UserConfigException(Exception): + """ + Raised when there is a problem with the values set in the UserConfig + class + """ diff --git a/snaps/openstack/create_user.py b/snaps/openstack/create_user.py index bbed133..5da3a5e 100644 --- a/snaps/openstack/create_user.py +++ b/snaps/openstack/create_user.py @@ -16,6 +16,7 @@ import logging from keystoneclient.exceptions import NotFound +from snaps.config.user import UserConfig from snaps.openstack.openstack_creator import OpenStackIdentityObject from snaps.openstack.os_credentials import OSCreds from snaps.openstack.utils import keystone_utils @@ -110,43 +111,15 @@ class OpenStackUser(OpenStackIdentityObject): cacert=self._os_creds.cacert) -class UserSettings: - def __init__(self, **kwargs): - - """ - Constructor - :param name: the user's name (required) - :param password: the user's password (required) - :param project_name: the user's primary project name (optional) - :param domain_name: the user's domain name (default='Default'). For v3 - APIs - :param email: the user's email address (optional) - :param enabled: denotes whether or not the user is enabled - (default True) - :param roles: dict where key is the role's name and value is the name - of the project to associate with the role (optional) - """ - - self.name = kwargs.get('name') - self.password = kwargs.get('password') - self.project_name = kwargs.get('project_name') - self.email = kwargs.get('email') - self.domain_name = kwargs.get('domain_name', 'Default') - self.enabled = kwargs.get('enabled', True) - self.roles = kwargs.get('roles', dict()) - - if not self.name or not self.password: - raise UserSettingsException( - 'The attributes name and password are required for ' - 'UserSettings') - - if not isinstance(self.enabled, bool): - raise UserSettingsException('The attribute enabled must be of type' - ' boolean') - - -class UserSettingsException(Exception): +class UserSettings(UserConfig): """ - Raised when there is a problem with the values set in the UserSettings - class + Class to hold the configuration settings required for creating OpenStack + user objects + deprecated """ + + def __init__(self, **kwargs): + from warnings import warn + warn('Use snaps.config.user.UserConfig instead', + DeprecationWarning) + super(self.__class__, self).__init__(**kwargs) diff --git a/snaps/openstack/tests/create_project_tests.py b/snaps/openstack/tests/create_project_tests.py index 178d3fe..d7d4dcf 100644 --- a/snaps/openstack/tests/create_project_tests.py +++ b/snaps/openstack/tests/create_project_tests.py @@ -17,6 +17,7 @@ import uuid from keystoneclient.exceptions import BadRequest +from snaps.config.user import UserConfig from snaps.config.project import ProjectConfigError, ProjectConfig from snaps.domain.project import ComputeQuotas, NetworkQuotas from snaps.openstack.create_project import ( @@ -24,7 +25,6 @@ from snaps.openstack.create_project import ( from snaps.openstack.create_security_group import OpenStackSecurityGroup from snaps.openstack.create_security_group import SecurityGroupSettings from snaps.openstack.create_user import OpenStackUser -from snaps.openstack.create_user import UserSettings from snaps.openstack.tests.os_source_file_test import OSComponentTestCase from snaps.openstack.utils import keystone_utils, nova_utils, neutron_utils @@ -273,10 +273,10 @@ class CreateProjectUserTests(OSComponentTestCase): self.assertIsNotNone(created_project) user_creator = OpenStackUser( - self.os_creds, UserSettings( + self.os_creds, UserConfig( name=self.guid + '-user', - password=self.guid, roles={ - 'admin': self.project_settings.name}, + password=self.guid, + roles={'admin': self.project_settings.name}, domain_name=self.os_creds.user_domain_name)) self.project_creator.assoc_user(user_creator.create()) self.user_creators.append(user_creator) @@ -304,7 +304,7 @@ class CreateProjectUserTests(OSComponentTestCase): self.assertIsNotNone(created_project) user_creator_1 = OpenStackUser( - self.os_creds, UserSettings( + self.os_creds, UserConfig( name=self.guid + '-user1', password=self.guid, roles={'admin': self.project_settings.name}, domain_name=self.os_creds.user_domain_name)) @@ -312,7 +312,7 @@ class CreateProjectUserTests(OSComponentTestCase): self.user_creators.append(user_creator_1) user_creator_2 = OpenStackUser( - self.os_creds, UserSettings( + self.os_creds, UserConfig( name=self.guid + '-user2', password=self.guid, roles={'admin': self.project_settings.name}, domain_name=self.os_creds.user_domain_name)) diff --git a/snaps/openstack/tests/create_user_tests.py b/snaps/openstack/tests/create_user_tests.py index ffae596..d3eb4a6 100644 --- a/snaps/openstack/tests/create_user_tests.py +++ b/snaps/openstack/tests/create_user_tests.py @@ -15,6 +15,7 @@ import unittest import uuid +from snaps.config.user import UserConfig from snaps.openstack.create_user import OpenStackUser, UserSettings from snaps.openstack.tests.os_source_file_test import OSComponentTestCase from snaps.openstack.utils import keystone_utils @@ -102,7 +103,7 @@ class CreateUserSuccessTests(OSComponentTestCase): """ guid = str(uuid.uuid4())[:-19] guid = self.__class__.__name__ + '-' + guid - self.user_settings = UserSettings( + self.user_settings = UserConfig( name=guid + '-name', password=guid + '-password', roles={'admin': self.os_creds.project_name}, diff --git a/snaps/openstack/tests/os_source_file_test.py b/snaps/openstack/tests/os_source_file_test.py index db54f10..ef4fcfa 100644 --- a/snaps/openstack/tests/os_source_file_test.py +++ b/snaps/openstack/tests/os_source_file_test.py @@ -19,7 +19,7 @@ import unittest from snaps import file_utils from snaps.config.project import ProjectConfig -from snaps.openstack.create_user import UserSettings +from snaps.config.user import UserConfig from snaps.openstack.tests import openstack_tests from snaps.openstack.utils import deploy_utils, keystone_utils @@ -150,7 +150,7 @@ class OSIntegrationTestCase(OSComponentTestCase): domain=self.admin_os_creds.project_domain_name)) self.user_creator = deploy_utils.create_user( - self.admin_os_creds, UserSettings( + self.admin_os_creds, UserConfig( name=guid + '-user', password=guid, project_name=project_name, roles={ 'admin': self.project_creator.project_settings.name}, diff --git a/snaps/openstack/utils/tests/keystone_utils_tests.py b/snaps/openstack/utils/tests/keystone_utils_tests.py index ef08acc..b7f024d 100644 --- a/snaps/openstack/utils/tests/keystone_utils_tests.py +++ b/snaps/openstack/utils/tests/keystone_utils_tests.py @@ -15,7 +15,7 @@ import uuid from snaps.config.project import ProjectConfig -from snaps.openstack.create_user import UserSettings +from snaps.config.user import UserConfig from snaps.openstack.tests.os_source_file_test import OSComponentTestCase from snaps.openstack.utils import keystone_utils, neutron_utils @@ -96,7 +96,7 @@ class KeystoneUtilsTests(OSComponentTestCase): """ Tests the keystone_utils.create_user() function """ - user_settings = UserSettings( + user_settings = UserConfig( name=self.username, password=str(uuid.uuid4()), domain_name=self.os_creds.user_domain_name) @@ -180,7 +180,7 @@ class KeystoneUtilsTests(OSComponentTestCase): Tests the keystone_utils function grant_user_role_to_project() :return: """ - user_settings = UserSettings( + user_settings = UserConfig( name=self.username, password=str(uuid.uuid4()), domain_name=self.os_creds.user_domain_name) self.user = keystone_utils.create_user(self.keystone, user_settings) diff --git a/snaps/test_suite_builder.py b/snaps/test_suite_builder.py index 235bb91..26acd5e 100644 --- a/snaps/test_suite_builder.py +++ b/snaps/test_suite_builder.py @@ -16,6 +16,7 @@ import logging import unittest +from snaps.config.tests.user_tests import UserConfigUnitTests from snaps.config.tests.project_tests import ProjectConfigUnitTests from snaps.config.tests.keypair_tests import KeypairConfigUnitTests from snaps.config.tests.flavor_tests import FlavorConfigUnitTests @@ -154,6 +155,8 @@ def add_unit_tests(suite): KeypairSettingsUnitTests)) suite.addTest(unittest.TestLoader().loadTestsFromTestCase( KeypairDomainObjectTests)) + suite.addTest(unittest.TestLoader().loadTestsFromTestCase( + UserConfigUnitTests)) suite.addTest(unittest.TestLoader().loadTestsFromTestCase( UserSettingsUnitTests)) suite.addTest(unittest.TestLoader().loadTestsFromTestCase( -- cgit 1.2.3-korg