Introduce separate module,state to work with v3 only
This patch introduce new keystonev3 module and state that uses
os_client_config library for authenticaion and raw client to send
requests directly to API.
Since v3 resource structure/resource relation are completely different
we introduce new pillar keystone:client:resources:v3 which will contain
all resources we manage via v3 client.
The module,state implements basic functionality to manage:
* users
* projects
* services
* endpoints
* roles
Other resources will be added in separate patches when needed.
Bootstrap of keystone is done via bootstrap script in server.sls in
Queens as admin token is removed.
Related-Prod: PROD-19148
Change-Id: I10a7cf720955437e3757a1c9699e4a60e1327ba3
diff --git a/_modules/keystonev3/roles.py b/_modules/keystonev3/roles.py
new file mode 100644
index 0000000..bd85c16
--- /dev/null
+++ b/_modules/keystonev3/roles.py
@@ -0,0 +1,95 @@
+from keystonev3.common import get_by_name_or_uuid, send
+from keystonev3.common import KeystoneException
+
+try:
+ from urllib.parse import urlencode
+except ImportError:
+ from urllib import urlencode
+
+
+@send('get')
+def role_list(**kwargs):
+ url = '/roles?{}'.format(urlencode(kwargs))
+ return url, None
+
+
+@send('get')
+def role_assignment_list(**kwargs):
+ url = '/role_assignments?{}'.format(urlencode(kwargs))
+ return url, None
+
+
+@send('put')
+def role_add(user_id, role_id, project_id=None, domain_id=None, **kwargs):
+ if (project_id and domain_id) or (not project_id and not domain_id):
+ raise KeystoneException('Role can be assigned either to project '
+ 'or domain.')
+ if project_id:
+ url = '/projects/{}/users/{}/roles/{}'.format(project_id, user_id,
+ role_id)
+ elif domain_id:
+ url = '/domains/{}/users/{}/roles/{}'.format(domain_id, user_id,
+ role_id)
+ return url, None
+
+
+@send('delete')
+def role_delete(user_id, role_id, project_id=None, domain_id=None, **kwargs):
+ if (project_id and domain_id) or (not project_id and not domain_id):
+ raise KeystoneException('Role can be unassigned either from project '
+ 'or domain.')
+ if project_id:
+ url = '/projects/{}/users/{}/roles/{}'.format(project_id, user_id,
+ role_id)
+ elif domain_id:
+ url = '/domains/{}/users/{}/roles/{}'.format(domain_id, user_id,
+ role_id)
+ return url, None
+
+
+@send('head')
+def role_assignment_check(user_id, role_id, project_id=None,
+ domain_id=None, **kwargs):
+ if (project_id and domain_id) or (not project_id and not domain_id):
+ raise KeystoneException('Role can be assigned either to project '
+ 'or domain.')
+ if project_id:
+ url = '/projects/{}/users/{}/roles/{}'.format(project_id, user_id,
+ role_id)
+ elif domain_id:
+ url = '/domains/{}/users/{}/roles/{}'.format(domain_id, user_id,
+ role_id)
+ return url, None
+
+
+@get_by_name_or_uuid(role_list, 'roles', 'role_id')
+@send('get')
+def role_get_details(role_id, **kwargs):
+ url = '/roles/{}?{}'.format(role_id, urlencode(kwargs))
+ return url, None
+
+
+@get_by_name_or_uuid(role_list, 'roles', 'role_id')
+@send('patch')
+def role_update(role_id, **kwargs):
+ url = '/roles/{}'.format(role_id)
+ json = {
+ 'role': kwargs,
+ }
+ return url, json
+
+
+@get_by_name_or_uuid(role_list, 'roles', 'role_id')
+@send('delete')
+def role_remove(role_id, **kwargs):
+ url = '/roles/{}'.format(role_id)
+ return url, None
+
+
+@send('post')
+def role_create(**kwargs):
+ url = '/roles'
+ json = {
+ 'role': kwargs,
+ }
+ return url, json