Refactoring of UserSettings to extend UserConfig 23/47423/2
authorspisarski <s.pisarski@cablelabs.com>
Fri, 17 Nov 2017 16:25:33 +0000 (09:25 -0700)
committerspisarski <s.pisarski@cablelabs.com>
Mon, 20 Nov 2017 15:15:10 +0000 (08:15 -0700)
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 <s.pisarski@cablelabs.com>
docs/how-to-use/LibraryUsage.rst
docs/how-to-use/UnitTests.rst
examples/launch.py
snaps/config/tests/user_tests.py [new file with mode: 0644]
snaps/config/user.py [new file with mode: 0644]
snaps/openstack/create_user.py
snaps/openstack/tests/create_project_tests.py
snaps/openstack/tests/create_user_tests.py
snaps/openstack/tests/os_source_file_test.py
snaps/openstack/utils/tests/keystone_utils_tests.py
snaps/test_suite_builder.py

index ae28212..b5cff12 100644 (file)
@@ -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()
 
index 214e2b8..e45a114 100644 (file)
@@ -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
 ---------------------
index d1129b0..0ed6456 100644 (file)
@@ -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 (file)
index 0000000..d3d8feb
--- /dev/null
@@ -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 (file)
index 0000000..fcc8fac
--- /dev/null
@@ -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
+    """
index bbed133..5da3a5e 100644 (file)
@@ -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)
index 178d3fe..d7d4dcf 100644 (file)
@@ -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))
index ffae596..d3eb4a6 100644 (file)
@@ -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},
index db54f10..ef4fcfa 100644 (file)
@@ -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},
index ef08acc..b7f024d 100644 (file)
@@ -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)
index 235bb91..26acd5e 100644 (file)
@@ -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(