Initial patch with all code from CableLabs repository.
[snaps.git] / snaps / openstack / utils / keystone_utils.py
diff --git a/snaps/openstack/utils/keystone_utils.py b/snaps/openstack/utils/keystone_utils.py
new file mode 100644 (file)
index 0000000..8175b9a
--- /dev/null
@@ -0,0 +1,204 @@
+# Copyright (c) 2016 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 requests
+from keystoneclient.client import Client
+from keystoneauth1.identity import v3, v2
+from keystoneauth1 import session
+import logging
+
+
+logger = logging.getLogger('keystone_utils')
+
+V2_VERSION = 'v2.0'
+
+
+def keystone_session(os_creds):
+    """
+    Creates a keystone session used for authenticating OpenStack clients
+    :param os_creds: The connection credentials to the OpenStack API
+    :return: the client object
+    """
+    logger.debug('Retrieving Keystone Session')
+
+    if os_creds.identity_api_version == 3:
+        auth = v3.Password(auth_url=os_creds.auth_url, username=os_creds.username, password=os_creds.password,
+                           project_name=os_creds.project_name, user_domain_id=os_creds.user_domain_id,
+                           project_domain_id=os_creds.project_domain_id)
+    else:
+        auth = v2.Password(auth_url=os_creds.auth_url, username=os_creds.username, password=os_creds.password,
+                           tenant_name=os_creds.project_name)
+
+    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}
+    return session.Session(auth=auth, session=req_session)
+
+
+def keystone_client(os_creds):
+    """
+    Returns the keystone client
+    :param os_creds: the OpenStack credentials (OSCreds) object
+    :return: the client
+    """
+    return Client(version=os_creds.identity_api_version, session=keystone_session(os_creds))
+
+
+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 project_name: the name to query
+    :return: the ID or None
+    """
+    if not project_name:
+        return None
+
+    if not keystone:
+        if os_creds:
+            keystone = keystone_client(os_creds)
+        else:
+            raise Exception('Cannot lookup project without the proper credentials')
+
+    if keystone.version == V2_VERSION:
+        projects = keystone.tenants.list()
+    else:
+        projects = keystone.projects.list(**{'name': project_name})
+
+    for project in projects:
+        if project.name == project_name:
+            return project
+
+    return None
+
+
+def create_project(keystone, project_settings):
+    """
+    Creates a project
+    :param keystone: the Keystone client
+    :param project_settings: the project configuration
+    :return:
+    """
+    if keystone.version == V2_VERSION:
+        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)
+
+
+def delete_project(keystone, project):
+    """
+    Deletes a project
+    :param keystone: the Keystone clien
+    :param project: the OpenStack project object
+    """
+    if keystone.version == V2_VERSION:
+        keystone.tenants.delete(project)
+    else:
+        keystone.projects.delete(project)
+
+
+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:
+    """
+    project = get_project(keystone=keystone, project_name=project_name)
+
+    if project:
+        users = keystone.users.list(tenant_id=project.id)
+    else:
+        users = keystone.users.list()
+
+    for user in users:
+        if user.name == username:
+            return user
+
+    return None
+
+
+def create_user(keystone, user_settings):
+    """
+    Creates a user
+    :param keystone: the Keystone client
+    :param user_settings: the user configuration
+    :return:
+    """
+    project = None
+    if 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)
+    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)
+
+
+def delete_user(keystone, user):
+    """
+    Deletes a user
+    :param keystone: the Keystone client
+    :param user: the OpenStack user object
+    """
+    keystone.users.delete(user)
+
+
+def create_role(keystone, name):
+    """
+    Creates an OpenStack role
+    :param keystone: the keystone client
+    :param name: the role name
+    :return:
+    """
+    return keystone.roles.create(name)
+
+
+def delete_role(keystone, role):
+    """
+    Deletes an OpenStack role
+    :param keystone: the keystone client
+    :param role: the role to delete
+    :return:
+    """
+    keystone.roles.delete(role)
+
+
+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 project: the project to which to add a user
+    :return:
+    """
+    if keystone.version == V2_VERSION:
+        keystone.roles.add_user_role(user, role, tenant=project)
+    else:
+        keystone.roles.grant(role, user=user, project=project)