Created domain object for users. 35/37035/2
authorspisarski <s.pisarski@cablelabs.com>
Thu, 6 Jul 2017 20:28:49 +0000 (14:28 -0600)
committerspisarski <s.pisarski@cablelabs.com>
Fri, 7 Jul 2017 14:26:48 +0000 (08:26 -0600)
OpenStack implementation details were leaking out into the
user creator.

JIRA: SNAPS-117

Change-Id: I67c77c75055b37819512d1e7712925b839fbc047
Signed-off-by: spisarski <s.pisarski@cablelabs.com>
snaps/domain/test/user_tests.py [new file with mode: 0644]
snaps/domain/user.py [new file with mode: 0644]
snaps/openstack/create_project.py
snaps/openstack/utils/keystone_utils.py
snaps/test_suite_builder.py

diff --git a/snaps/domain/test/user_tests.py b/snaps/domain/test/user_tests.py
new file mode 100644 (file)
index 0000000..c9b82c8
--- /dev/null
@@ -0,0 +1,33 @@
+# 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.domain.user import User
+
+
+class UserDomainObjectTests(unittest.TestCase):
+    """
+    Tests the construction of the snaps.domain.test.User class
+    """
+
+    def test_construction_positional(self):
+        user = User('foo', '123-456')
+        self.assertEqual('foo', user.name)
+        self.assertEqual('123-456', user.id)
+
+    def test_construction_named(self):
+        user = User(user_id='123-456', name='foo')
+        self.assertEqual('foo', user.name)
+        self.assertEqual('123-456', user.id)
diff --git a/snaps/domain/user.py b/snaps/domain/user.py
new file mode 100644 (file)
index 0000000..0631642
--- /dev/null
@@ -0,0 +1,32 @@
+# 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 User:
+    """
+    SNAPS domain object for Users. Should contain attributes that
+    are shared amongst cloud providers
+    """
+    def __init__(self, name, user_id):
+        """
+        Constructor
+        :param name: the user's name
+        :param id: the user's id
+        """
+        self.name = name
+        self.id = user_id
+
+    def __eq__(self, other):
+        return self.name == other.name and self.id == other.id
index 8d72fdb..c865f15 100644 (file)
@@ -89,7 +89,7 @@ class OpenStackProject:
     def assoc_user(self, user):
         """
         The user object to associate with the project
-        :param user: the OpenStack user object to associate with project
+        :param user: the OpenStack User domain object to associate with project
         :return:
         """
         if not self.__role:
index 061f3f0..f0de567 100644 (file)
@@ -19,6 +19,8 @@ from keystoneauth1.identity import v3, v2
 from keystoneauth1 import session
 import requests
 
+from snaps.domain.user import User
+
 logger = logging.getLogger('keystone_utils')
 
 V2_VERSION = 'v2.0'
@@ -58,7 +60,10 @@ def keystone_session(os_creds):
     req_session = None
     if os_creds.proxy_settings:
         req_session = requests.Session()
-        req_session.proxies = {'http': os_creds.proxy_settings.host + ':' + os_creds.proxy_settings.port}
+        req_session.proxies = {
+            'http':
+                os_creds.proxy_settings.host + ':' +
+                os_creds.proxy_settings.port}
     return session.Session(auth=auth, session=req_session,
                            verify=os_creds.cacert)
 
@@ -69,8 +74,9 @@ def keystone_client(os_creds):
     :param os_creds: the OpenStack credentials (OSCreds) object
     :return: the client
     """
-    return Client(version=os_creds.identity_api_version, session=keystone_session(os_creds),
-                  interface=os_creds.interface)
+    return Client(
+        version=os_creds.identity_api_version,
+        session=keystone_session(os_creds), interface=os_creds.interface)
 
 
 def get_endpoint(os_creds, service_type, endpoint_type='publicURL'):
@@ -83,14 +89,16 @@ def get_endpoint(os_creds, service_type, endpoint_type='publicURL'):
     """
     auth = get_session_auth(os_creds)
     key_session = keystone_session(os_creds)
-    return key_session.get_endpoint(auth=auth, service_type=service_type, endpoint_type=endpoint_type)
+    return key_session.get_endpoint(
+        auth=auth, service_type=service_type, endpoint_type=endpoint_type)
 
 
 def get_project(keystone=None, os_creds=None, project_name=None):
     """
     Returns the first project object or None if not found
     :param keystone: the Keystone client
-    :param os_creds: the OpenStack credentials used to obtain the Keystone client if the keystone parameter is None
+    :param os_creds: the OpenStack credentials used to obtain the Keystone
+                     client if the keystone parameter is None
     :param project_name: the name to query
     :return: the ID or None
     """
@@ -101,7 +109,8 @@ def get_project(keystone=None, os_creds=None, project_name=None):
         if os_creds:
             keystone = keystone_client(os_creds)
         else:
-            raise Exception('Cannot lookup project without the proper credentials')
+            raise Exception('Cannot lookup project without the proper '
+                            'credentials')
 
     if keystone.version == V2_VERSION:
         projects = keystone.tenants.list()
@@ -123,11 +132,14 @@ def create_project(keystone, project_settings):
     :return:
     """
     if keystone.version == V2_VERSION:
-        return keystone.tenants.create(project_settings.name, project_settings.description, project_settings.enabled)
+        return keystone.tenants.create(
+            project_settings.name, project_settings.description,
+            project_settings.enabled)
 
-    return keystone.projects.create(project_settings.name, project_settings.domain,
-                                    description=project_settings.description,
-                                    enabled=project_settings.enabled)
+    return keystone.projects.create(
+        project_settings.name, project_settings.domain,
+        description=project_settings.description,
+        enabled=project_settings.enabled)
 
 
 def delete_project(keystone, project):
@@ -142,13 +154,23 @@ def delete_project(keystone, project):
         keystone.projects.delete(project)
 
 
+def get_os_user(keystone, user):
+    """
+    Returns the OpenStack user object
+    :param keystone: the Keystone client object
+    :param user: the SNAPS-OO User domain object
+    :return:
+    """
+    return keystone.users.get(user.id)
+
+
 def get_user(keystone, username, project_name=None):
     """
     Returns a user for a given name and optionally project
     :param keystone: the keystone client
     :param username: the username to lookup
     :param project_name: the associated project (optional)
-    :return:
+    :return: a SNAPS-OO User domain object or None
     """
     project = get_project(keystone=keystone, project_name=project_name)
 
@@ -159,7 +181,7 @@ def get_user(keystone, username, project_name=None):
 
     for user in users:
         if user.name == username:
-            return user
+            return User(name=user.name, user_id=user.id)
 
     return None
 
@@ -169,34 +191,39 @@ def create_user(keystone, user_settings):
     Creates a user
     :param keystone: the Keystone client
     :param user_settings: the user configuration
-    :return:
+    :return: a SNAPS-OO User domain object
     """
     project = None
     if user_settings.project_name:
-        project = get_project(keystone=keystone, project_name=user_settings.project_name)
+        project = get_project(keystone=keystone,
+                              project_name=user_settings.project_name)
 
     if keystone.version == V2_VERSION:
         project_id = None
         if project:
             project_id = project.id
-        return keystone.users.create(name=user_settings.name, password=user_settings.password,
-                                     email=user_settings.email, tenant_id=project_id, enabled=user_settings.enabled)
+        os_user = keystone.users.create(
+            name=user_settings.name, password=user_settings.password,
+            email=user_settings.email, tenant_id=project_id,
+            enabled=user_settings.enabled)
     else:
         # TODO - need to support groups
-        return keystone.users.create(name=user_settings.name, password=user_settings.password,
-                                     email=user_settings.email, project=project,
-                                     # email=user_settings.email, project=project, group='default',
-                                     domain=user_settings.domain_name,
-                                     enabled=user_settings.enabled)
+        os_user = keystone.users.create(
+            name=user_settings.name, password=user_settings.password,
+            email=user_settings.email, project=project,
+            domain=user_settings.domain_name, enabled=user_settings.enabled)
+
+    if os_user:
+        return User(name=os_user.name, user_id=os_user.id)
 
 
 def delete_user(keystone, user):
     """
     Deletes a user
     :param keystone: the Keystone client
-    :param user: the OpenStack user object
+    :param user: the SNAPS-OO User domain object
     """
-    keystone.users.delete(user)
+    keystone.users.delete(user.id)
 
 
 def create_role(keystone, name):
@@ -224,7 +251,7 @@ def assoc_user_to_project(keystone, role, user, project):
     Adds a user to a project
     :param keystone: the Keystone client
     :param role: the role used to join a project/user
-    :param user: the user to add to the project
+    :param user: the user to add to the project (SNAPS-OO User Domain object
     :param project: the project to which to add a user
     :return:
     """
index e3389a9..2187f94 100644 (file)
@@ -20,6 +20,7 @@ from snaps.domain.test.flavor_tests import FlavorDomainObjectTests
 from snaps.domain.test.image_tests import ImageDomainObjectTests
 from snaps.domain.test.keypair_tests import KeypairDomainObjectTests
 from snaps.domain.test.stack_tests import StackDomainObjectTests
+from snaps.domain.test.user_tests import UserDomainObjectTests
 from snaps.domain.test.vm_inst_tests import (VmInstDomainObjectTests,
                                              FloatingIpDomainObjectTests)
 from snaps.openstack.tests.conf.os_credentials_tests import (
@@ -104,6 +105,8 @@ def add_unit_tests(suite):
         KeypairDomainObjectTests))
     suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
         UserSettingsUnitTests))
+    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
+        UserDomainObjectTests))
     suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
         ProjectSettingsUnitTests))
     suite.addTest(unittest.TestLoader().loadTestsFromTestCase(