1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
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:
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 from keystoneclient.client import Client
18 from keystoneauth1.identity import v3, v2
19 from keystoneauth1 import session
22 from snaps.domain.user import User
24 logger = logging.getLogger('keystone_utils')
29 def get_session_auth(os_creds):
31 Return the session auth for keystone session
32 :param os_creds: the OpenStack credentials (OSCreds) object
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)
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)
50 def keystone_session(os_creds):
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
56 logger.debug('Retrieving Keystone Session')
58 auth = get_session_auth(os_creds)
61 if os_creds.proxy_settings:
62 req_session = requests.Session()
63 req_session.proxies = {
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)
71 def keystone_client(os_creds):
73 Returns the keystone client
74 :param os_creds: the OpenStack credentials (OSCreds) object
78 version=os_creds.identity_api_version,
79 session=keystone_session(os_creds), interface=os_creds.interface)
82 def get_endpoint(os_creds, service_type, endpoint_type='publicURL'):
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
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)
96 def get_project(keystone=None, os_creds=None, project_name=None):
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
110 keystone = keystone_client(os_creds)
112 raise Exception('Cannot lookup project without the proper '
115 if keystone.version == V2_VERSION:
116 projects = keystone.tenants.list()
118 projects = keystone.projects.list(**{'name': project_name})
120 for project in projects:
121 if project.name == project_name:
127 def create_project(keystone, project_settings):
130 :param keystone: the Keystone client
131 :param project_settings: the project configuration
134 if keystone.version == V2_VERSION:
135 return keystone.tenants.create(
136 project_settings.name, project_settings.description,
137 project_settings.enabled)
139 return keystone.projects.create(
140 project_settings.name, project_settings.domain,
141 description=project_settings.description,
142 enabled=project_settings.enabled)
145 def delete_project(keystone, project):
148 :param keystone: the Keystone clien
149 :param project: the OpenStack project object
151 if keystone.version == V2_VERSION:
152 keystone.tenants.delete(project)
154 keystone.projects.delete(project)
157 def get_os_user(keystone, user):
159 Returns the OpenStack user object
160 :param keystone: the Keystone client object
161 :param user: the SNAPS-OO User domain object
164 return keystone.users.get(user.id)
167 def get_user(keystone, username, project_name=None):
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
175 project = get_project(keystone=keystone, project_name=project_name)
178 users = keystone.users.list(tenant_id=project.id)
180 users = keystone.users.list()
183 if user.name == username:
184 return User(name=user.name, user_id=user.id)
189 def create_user(keystone, user_settings):
192 :param keystone: the Keystone client
193 :param user_settings: the user configuration
194 :return: a SNAPS-OO User domain object
197 if user_settings.project_name:
198 project = get_project(keystone=keystone,
199 project_name=user_settings.project_name)
201 if keystone.version == V2_VERSION:
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)
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)
217 return User(name=os_user.name, user_id=os_user.id)
220 def delete_user(keystone, user):
223 :param keystone: the Keystone client
224 :param user: the SNAPS-OO User domain object
226 keystone.users.delete(user.id)
229 def create_role(keystone, name):
231 Creates an OpenStack role
232 :param keystone: the keystone client
233 :param name: the role name
236 return keystone.roles.create(name)
239 def delete_role(keystone, role):
241 Deletes an OpenStack role
242 :param keystone: the keystone client
243 :param role: the role to delete
246 keystone.roles.delete(role)
249 def assoc_user_to_project(keystone, role, user, project):
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
258 if keystone.version == V2_VERSION:
259 keystone.roles.add_user_role(user, role, tenant=project)
261 keystone.roles.grant(role, user=user, project=project)