Created domain class for roles. 97/37397/1
authorspisarski <s.pisarski@cablelabs.com>
Thu, 13 Jul 2017 14:15:40 +0000 (08:15 -0600)
committerspisarski <s.pisarski@cablelabs.com>
Thu, 13 Jul 2017 14:15:40 +0000 (08:15 -0600)
Create Role domain class so keystone_utils.py functions returning
role objects will not be leaking out implementation details as each
API version can change these data structures and this should all be
handled by the SNAPS neutron utility.

JIRA: SNAPS-119

Change-Id: I6918a45c1c414ee6b104ec36e63c540d6f656e30
Signed-off-by: spisarski <s.pisarski@cablelabs.com>
snaps/domain/role.py [new file with mode: 0644]
snaps/domain/test/role_tests.py [new file with mode: 0644]
snaps/openstack/tests/create_user_tests.py
snaps/openstack/utils/keystone_utils.py
snaps/openstack/utils/tests/keystone_utils_tests.py
snaps/test_suite_builder.py

diff --git a/snaps/domain/role.py b/snaps/domain/role.py
new file mode 100644 (file)
index 0000000..565a3f2
--- /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 Role:
+    """
+    SNAPS domain object for Roles. Should contain attributes that
+    are shared amongst cloud providers
+    """
+    def __init__(self, name, role_id):
+        """
+        Constructor
+        :param name: the user's name
+        :param id: the user's id
+        """
+        self.name = name
+        self.id = role_id
+
+    def __eq__(self, other):
+        return self.name == other.name and self.id == other.id
diff --git a/snaps/domain/test/role_tests.py b/snaps/domain/test/role_tests.py
new file mode 100644 (file)
index 0000000..541b22d
--- /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.role import Role
+
+
+class RoleDomainObjectTests(unittest.TestCase):
+    """
+    Tests the construction of the snaps.domain.test.Role class
+    """
+
+    def test_construction_positional(self):
+        role = Role('foo', '123-456')
+        self.assertEqual('foo', role.name)
+        self.assertEqual('123-456', role.id)
+
+    def test_construction_named(self):
+        role = Role(role_id='123-456', name='foo')
+        self.assertEqual('foo', role.name)
+        self.assertEqual('123-456', role.id)
index a3cc8ce..96de61e 100644 (file)
@@ -177,12 +177,12 @@ class CreateUserSuccessTests(OSComponentTestCase):
         self.assertIsNotNone(retrieved_user)
         self.assertEqual(created_user, retrieved_user)
 
-        role = keystone_utils.get_os_role_by_name(self.keystone, 'admin')
+        role = keystone_utils._get_os_role_by_name(self.keystone, 'admin')
         self.assertIsNotNone(role)
 
         os_proj = keystone_utils.get_project(
             keystone=self.keystone, project_name=self.os_creds.project_name)
-        user_roles = keystone_utils.get_os_roles_by_user(
+        user_roles = keystone_utils._get_os_roles_by_user(
             self.keystone, retrieved_user, os_proj)
         self.assertIsNotNone(user_roles)
         self.assertEqual(1, len(user_roles))
index 6812828..92e4b64 100644 (file)
@@ -20,6 +20,7 @@ from keystoneauth1 import session
 import requests
 
 from snaps.domain.project import Project
+from snaps.domain.role import Role
 from snaps.domain.user import User
 
 logger = logging.getLogger('keystone_utils')
@@ -155,7 +156,7 @@ def delete_project(keystone, project):
         keystone.projects.delete(project.id)
 
 
-def get_os_user(keystone, user):
+def __get_os_user(keystone, user):
     """
     Returns the OpenStack user object
     :param keystone: the Keystone client object
@@ -214,12 +215,12 @@ def create_user(keystone, user_settings):
             domain=user_settings.domain_name, enabled=user_settings.enabled)
 
     for role_name, role_project in user_settings.roles.items():
-        os_role = get_os_role_by_name(keystone, role_name)
+        os_role = _get_os_role_by_name(keystone, role_name)
         os_project = get_project(keystone=keystone, project_name=role_project)
 
         if os_role and os_project:
-            existing_roles = get_os_roles_by_user(keystone, os_user,
-                                                  os_project)
+            existing_roles = _get_os_roles_by_user(keystone, os_user,
+                                                   os_project)
             found = False
             for role in existing_roles:
                 if role.id == os_role.id:
@@ -243,43 +244,48 @@ def delete_user(keystone, user):
     keystone.users.delete(user.id)
 
 
-def get_os_role_by_name(keystone, name):
+def _get_os_role_by_name(keystone, name):
     """
     Returns an OpenStack role object of a given name or None if not exists
     :param keystone: the keystone client
     :param name: the role name
-    :return: the OpenStack role object
+    :return: the SNAPS-OO Role domain object
     """
     roles = keystone.roles.list()
     for role in roles:
         if role.name == name:
-            return role
+            return Role(name=role.name, role_id=role.id)
 
 
-def get_os_roles_by_user(keystone, user, project):
+def _get_os_roles_by_user(keystone, user, project):
     """
     Returns a list of OpenStack role object associated with a user
     :param keystone: the keystone client
     :param user: the OpenStack user object
     :param project: the OpenStack project object (only required for v2)
-    :return: a list of OpenStack role objects
+    :return: a list of SNAPS-OO Role domain objects
     """
     if keystone.version == V2_VERSION:
-        os_user = get_os_user(keystone, user)
+        os_user = __get_os_user(keystone, user)
         roles = keystone.roles.roles_for_user(os_user, project)
-        return roles
     else:
-        return keystone.roles.list(user=user, project=project)
+        roles = keystone.roles.list(user=user, project=project)
+
+    out = list()
+    for role in roles:
+        out.append(Role(name=role.name, role_id=role.id))
+    return out
 
 
-def get_os_role_by_id(keystone, role_id):
+def __get_os_role_by_id(keystone, role_id):
     """
     Returns an OpenStack role object of a given name or None if not exists
     :param keystone: the keystone client
     :param role_id: the role ID
-    :return: the OpenStack role object
+    :return: a SNAPS-OO Role domain object
     """
-    return keystone.roles.get(role_id)
+    role = keystone.roles.get(role_id)
+    return Role(name=role.name, role_id=role.id)
 
 
 def create_role(keystone, name):
@@ -287,31 +293,34 @@ def create_role(keystone, name):
     Creates an OpenStack role
     :param keystone: the keystone client
     :param name: the role name
-    :return:
+    :return: a SNAPS-OO Role domain object
     """
-    return keystone.roles.create(name)
+    role = keystone.roles.create(name)
+    return Role(name=role.name, role_id=role.id)
 
 
 def delete_role(keystone, role):
     """
     Deletes an OpenStack role
     :param keystone: the keystone client
-    :param role: the role to delete
+    :param role: the SNAPS-OO Role domain object to delete
     :return:
     """
-    keystone.roles.delete(role)
+    keystone.roles.delete(role.id)
 
 
 def grant_user_role_to_project(keystone, role, user, project):
     """
     Grants user and role to a project
     :param keystone: the Keystone client
-    :param role: the role used to join a project/user
+    :param role: the SNAPS-OO Role domain object used to join a project/user
     :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:
     """
+
+    os_role = __get_os_role_by_id(keystone, role.id)
     if keystone.version == V2_VERSION:
-        keystone.roles.add_user_role(user, role, tenant=project)
+        keystone.roles.add_user_role(user, os_role, tenant=project)
     else:
-        keystone.roles.grant(role, user=user, project=project)
+        keystone.roles.grant(os_role, user=user, project=project)
index 336b9ea..ca5a0fa 100644 (file)
@@ -178,7 +178,7 @@ class KeystoneUtilsTests(OSComponentTestCase):
         keystone_utils.grant_user_role_to_project(
             self.keystone, self.role, self.user, self.project)
 
-        user_roles = keystone_utils.get_os_roles_by_user(
+        user_roles = keystone_utils._get_os_roles_by_user(
             self.keystone, self.user, self.project)
         self.assertIsNotNone(user_roles)
         self.assertEqual(1, len(user_roles))
index ab044e9..59acc2b 100644 (file)
@@ -23,6 +23,7 @@ from snaps.domain.test.network_tests import (
     SecurityGroupDomainObjectTests, SecurityGroupRuleDomainObjectTests,
     PortDomainObjectTests)
 from snaps.domain.test.project_tests import ProjectDomainObjectTests
+from snaps.domain.test.role_tests import RoleDomainObjectTests
 from snaps.domain.test.stack_tests import StackDomainObjectTests
 from snaps.domain.test.user_tests import UserDomainObjectTests
 from snaps.domain.test.vm_inst_tests import (
@@ -119,6 +120,8 @@ def add_unit_tests(suite):
         ProjectSettingsUnitTests))
     suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
         ProjectDomainObjectTests))
+    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
+        RoleDomainObjectTests))
     suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
         NetworkSettingsUnitTests))
     suite.addTest(unittest.TestLoader().loadTestsFromTestCase(