061f3f0951e9619bb9837f95c978ca839efe6eec
[snaps.git] / snaps / openstack / utils / keystone_utils.py
1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 import logging
16
17 from keystoneclient.client import Client
18 from keystoneauth1.identity import v3, v2
19 from keystoneauth1 import session
20 import requests
21
22 logger = logging.getLogger('keystone_utils')
23
24 V2_VERSION = 'v2.0'
25
26
27 def get_session_auth(os_creds):
28     """
29     Return the session auth for keystone session
30     :param os_creds: the OpenStack credentials (OSCreds) object
31     :return: the auth
32     """
33     if os_creds.identity_api_version == 3:
34         auth = v3.Password(auth_url=os_creds.auth_url,
35                            username=os_creds.username,
36                            password=os_creds.password,
37                            project_name=os_creds.project_name,
38                            user_domain_id=os_creds.user_domain_id,
39                            project_domain_id=os_creds.project_domain_id)
40     else:
41         auth = v2.Password(auth_url=os_creds.auth_url,
42                            username=os_creds.username,
43                            password=os_creds.password,
44                            tenant_name=os_creds.project_name)
45     return auth
46
47
48 def keystone_session(os_creds):
49     """
50     Creates a keystone session used for authenticating OpenStack clients
51     :param os_creds: The connection credentials to the OpenStack API
52     :return: the client object
53     """
54     logger.debug('Retrieving Keystone Session')
55
56     auth = get_session_auth(os_creds)
57
58     req_session = None
59     if os_creds.proxy_settings:
60         req_session = requests.Session()
61         req_session.proxies = {'http': os_creds.proxy_settings.host + ':' + os_creds.proxy_settings.port}
62     return session.Session(auth=auth, session=req_session,
63                            verify=os_creds.cacert)
64
65
66 def keystone_client(os_creds):
67     """
68     Returns the keystone client
69     :param os_creds: the OpenStack credentials (OSCreds) object
70     :return: the client
71     """
72     return Client(version=os_creds.identity_api_version, session=keystone_session(os_creds),
73                   interface=os_creds.interface)
74
75
76 def get_endpoint(os_creds, service_type, endpoint_type='publicURL'):
77     """
78     Returns the endpoint of specific service
79     :param os_creds: the OpenStack credentials (OSCreds) object
80     :param service_type: the type of specific service
81     :param endpoint_type: the type of endpoint
82     :return: the endpoint url
83     """
84     auth = get_session_auth(os_creds)
85     key_session = keystone_session(os_creds)
86     return key_session.get_endpoint(auth=auth, service_type=service_type, endpoint_type=endpoint_type)
87
88
89 def get_project(keystone=None, os_creds=None, project_name=None):
90     """
91     Returns the first project object or None if not found
92     :param keystone: the Keystone client
93     :param os_creds: the OpenStack credentials used to obtain the Keystone client if the keystone parameter is None
94     :param project_name: the name to query
95     :return: the ID or None
96     """
97     if not project_name:
98         return None
99
100     if not keystone:
101         if os_creds:
102             keystone = keystone_client(os_creds)
103         else:
104             raise Exception('Cannot lookup project without the proper credentials')
105
106     if keystone.version == V2_VERSION:
107         projects = keystone.tenants.list()
108     else:
109         projects = keystone.projects.list(**{'name': project_name})
110
111     for project in projects:
112         if project.name == project_name:
113             return project
114
115     return None
116
117
118 def create_project(keystone, project_settings):
119     """
120     Creates a project
121     :param keystone: the Keystone client
122     :param project_settings: the project configuration
123     :return:
124     """
125     if keystone.version == V2_VERSION:
126         return keystone.tenants.create(project_settings.name, project_settings.description, project_settings.enabled)
127
128     return keystone.projects.create(project_settings.name, project_settings.domain,
129                                     description=project_settings.description,
130                                     enabled=project_settings.enabled)
131
132
133 def delete_project(keystone, project):
134     """
135     Deletes a project
136     :param keystone: the Keystone clien
137     :param project: the OpenStack project object
138     """
139     if keystone.version == V2_VERSION:
140         keystone.tenants.delete(project)
141     else:
142         keystone.projects.delete(project)
143
144
145 def get_user(keystone, username, project_name=None):
146     """
147     Returns a user for a given name and optionally project
148     :param keystone: the keystone client
149     :param username: the username to lookup
150     :param project_name: the associated project (optional)
151     :return:
152     """
153     project = get_project(keystone=keystone, project_name=project_name)
154
155     if project:
156         users = keystone.users.list(tenant_id=project.id)
157     else:
158         users = keystone.users.list()
159
160     for user in users:
161         if user.name == username:
162             return user
163
164     return None
165
166
167 def create_user(keystone, user_settings):
168     """
169     Creates a user
170     :param keystone: the Keystone client
171     :param user_settings: the user configuration
172     :return:
173     """
174     project = None
175     if user_settings.project_name:
176         project = get_project(keystone=keystone, project_name=user_settings.project_name)
177
178     if keystone.version == V2_VERSION:
179         project_id = None
180         if project:
181             project_id = project.id
182         return keystone.users.create(name=user_settings.name, password=user_settings.password,
183                                      email=user_settings.email, tenant_id=project_id, enabled=user_settings.enabled)
184     else:
185         # TODO - need to support groups
186         return keystone.users.create(name=user_settings.name, password=user_settings.password,
187                                      email=user_settings.email, project=project,
188                                      # email=user_settings.email, project=project, group='default',
189                                      domain=user_settings.domain_name,
190                                      enabled=user_settings.enabled)
191
192
193 def delete_user(keystone, user):
194     """
195     Deletes a user
196     :param keystone: the Keystone client
197     :param user: the OpenStack user object
198     """
199     keystone.users.delete(user)
200
201
202 def create_role(keystone, name):
203     """
204     Creates an OpenStack role
205     :param keystone: the keystone client
206     :param name: the role name
207     :return:
208     """
209     return keystone.roles.create(name)
210
211
212 def delete_role(keystone, role):
213     """
214     Deletes an OpenStack role
215     :param keystone: the keystone client
216     :param role: the role to delete
217     :return:
218     """
219     keystone.roles.delete(role)
220
221
222 def assoc_user_to_project(keystone, role, user, project):
223     """
224     Adds a user to a project
225     :param keystone: the Keystone client
226     :param role: the role used to join a project/user
227     :param user: the user to add to the project
228     :param project: the project to which to add a user
229     :return:
230     """
231     if keystone.version == V2_VERSION:
232         keystone.roles.add_user_role(user, role, tenant=project)
233     else:
234         keystone.roles.grant(role, user=user, project=project)