Created domain object for users.
[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 from snaps.domain.user import User
23
24 logger = logging.getLogger('keystone_utils')
25
26 V2_VERSION = 'v2.0'
27
28
29 def get_session_auth(os_creds):
30     """
31     Return the session auth for keystone session
32     :param os_creds: the OpenStack credentials (OSCreds) object
33     :return: the auth
34     """
35     if os_creds.identity_api_version == 3:
36         auth = v3.Password(auth_url=os_creds.auth_url,
37                            username=os_creds.username,
38                            password=os_creds.password,
39                            project_name=os_creds.project_name,
40                            user_domain_id=os_creds.user_domain_id,
41                            project_domain_id=os_creds.project_domain_id)
42     else:
43         auth = v2.Password(auth_url=os_creds.auth_url,
44                            username=os_creds.username,
45                            password=os_creds.password,
46                            tenant_name=os_creds.project_name)
47     return auth
48
49
50 def keystone_session(os_creds):
51     """
52     Creates a keystone session used for authenticating OpenStack clients
53     :param os_creds: The connection credentials to the OpenStack API
54     :return: the client object
55     """
56     logger.debug('Retrieving Keystone Session')
57
58     auth = get_session_auth(os_creds)
59
60     req_session = None
61     if os_creds.proxy_settings:
62         req_session = requests.Session()
63         req_session.proxies = {
64             'http':
65                 os_creds.proxy_settings.host + ':' +
66                 os_creds.proxy_settings.port}
67     return session.Session(auth=auth, session=req_session,
68                            verify=os_creds.cacert)
69
70
71 def keystone_client(os_creds):
72     """
73     Returns the keystone client
74     :param os_creds: the OpenStack credentials (OSCreds) object
75     :return: the client
76     """
77     return Client(
78         version=os_creds.identity_api_version,
79         session=keystone_session(os_creds), interface=os_creds.interface)
80
81
82 def get_endpoint(os_creds, service_type, endpoint_type='publicURL'):
83     """
84     Returns the endpoint of specific service
85     :param os_creds: the OpenStack credentials (OSCreds) object
86     :param service_type: the type of specific service
87     :param endpoint_type: the type of endpoint
88     :return: the endpoint url
89     """
90     auth = get_session_auth(os_creds)
91     key_session = keystone_session(os_creds)
92     return key_session.get_endpoint(
93         auth=auth, service_type=service_type, endpoint_type=endpoint_type)
94
95
96 def get_project(keystone=None, os_creds=None, project_name=None):
97     """
98     Returns the first project object or None if not found
99     :param keystone: the Keystone client
100     :param os_creds: the OpenStack credentials used to obtain the Keystone
101                      client if the keystone parameter is None
102     :param project_name: the name to query
103     :return: the ID or None
104     """
105     if not project_name:
106         return None
107
108     if not keystone:
109         if os_creds:
110             keystone = keystone_client(os_creds)
111         else:
112             raise Exception('Cannot lookup project without the proper '
113                             'credentials')
114
115     if keystone.version == V2_VERSION:
116         projects = keystone.tenants.list()
117     else:
118         projects = keystone.projects.list(**{'name': project_name})
119
120     for project in projects:
121         if project.name == project_name:
122             return project
123
124     return None
125
126
127 def create_project(keystone, project_settings):
128     """
129     Creates a project
130     :param keystone: the Keystone client
131     :param project_settings: the project configuration
132     :return:
133     """
134     if keystone.version == V2_VERSION:
135         return keystone.tenants.create(
136             project_settings.name, project_settings.description,
137             project_settings.enabled)
138
139     return keystone.projects.create(
140         project_settings.name, project_settings.domain,
141         description=project_settings.description,
142         enabled=project_settings.enabled)
143
144
145 def delete_project(keystone, project):
146     """
147     Deletes a project
148     :param keystone: the Keystone clien
149     :param project: the OpenStack project object
150     """
151     if keystone.version == V2_VERSION:
152         keystone.tenants.delete(project)
153     else:
154         keystone.projects.delete(project)
155
156
157 def get_os_user(keystone, user):
158     """
159     Returns the OpenStack user object
160     :param keystone: the Keystone client object
161     :param user: the SNAPS-OO User domain object
162     :return:
163     """
164     return keystone.users.get(user.id)
165
166
167 def get_user(keystone, username, project_name=None):
168     """
169     Returns a user for a given name and optionally project
170     :param keystone: the keystone client
171     :param username: the username to lookup
172     :param project_name: the associated project (optional)
173     :return: a SNAPS-OO User domain object or None
174     """
175     project = get_project(keystone=keystone, project_name=project_name)
176
177     if project:
178         users = keystone.users.list(tenant_id=project.id)
179     else:
180         users = keystone.users.list()
181
182     for user in users:
183         if user.name == username:
184             return User(name=user.name, user_id=user.id)
185
186     return None
187
188
189 def create_user(keystone, user_settings):
190     """
191     Creates a user
192     :param keystone: the Keystone client
193     :param user_settings: the user configuration
194     :return: a SNAPS-OO User domain object
195     """
196     project = None
197     if user_settings.project_name:
198         project = get_project(keystone=keystone,
199                               project_name=user_settings.project_name)
200
201     if keystone.version == V2_VERSION:
202         project_id = None
203         if project:
204             project_id = project.id
205         os_user = keystone.users.create(
206             name=user_settings.name, password=user_settings.password,
207             email=user_settings.email, tenant_id=project_id,
208             enabled=user_settings.enabled)
209     else:
210         # TODO - need to support groups
211         os_user = keystone.users.create(
212             name=user_settings.name, password=user_settings.password,
213             email=user_settings.email, project=project,
214             domain=user_settings.domain_name, enabled=user_settings.enabled)
215
216     if os_user:
217         return User(name=os_user.name, user_id=os_user.id)
218
219
220 def delete_user(keystone, user):
221     """
222     Deletes a user
223     :param keystone: the Keystone client
224     :param user: the SNAPS-OO User domain object
225     """
226     keystone.users.delete(user.id)
227
228
229 def create_role(keystone, name):
230     """
231     Creates an OpenStack role
232     :param keystone: the keystone client
233     :param name: the role name
234     :return:
235     """
236     return keystone.roles.create(name)
237
238
239 def delete_role(keystone, role):
240     """
241     Deletes an OpenStack role
242     :param keystone: the keystone client
243     :param role: the role to delete
244     :return:
245     """
246     keystone.roles.delete(role)
247
248
249 def assoc_user_to_project(keystone, role, user, project):
250     """
251     Adds a user to a project
252     :param keystone: the Keystone client
253     :param role: the role used to join a project/user
254     :param user: the user to add to the project (SNAPS-OO User Domain object
255     :param project: the project to which to add a user
256     :return:
257     """
258     if keystone.version == V2_VERSION:
259         keystone.roles.add_user_role(user, role, tenant=project)
260     else:
261         keystone.roles.grant(role, user=user, project=project)