Convert domains api to flask
Convert domains api to flask native dispatching. Change-Id: I974ab112986e6c242a139f7d7dc14fd54a48ee42 Partial-Bug: #1776504
This commit is contained in:
parent
4975b79e81
commit
296f20f0a7
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
from keystone.api import credentials
|
from keystone.api import credentials
|
||||||
from keystone.api import discovery
|
from keystone.api import discovery
|
||||||
|
from keystone.api import domains
|
||||||
from keystone.api import endpoints
|
from keystone.api import endpoints
|
||||||
from keystone.api import groups
|
from keystone.api import groups
|
||||||
from keystone.api import limits
|
from keystone.api import limits
|
||||||
@ -34,6 +35,7 @@ from keystone.api import trusts
|
|||||||
__all__ = (
|
__all__ = (
|
||||||
'discovery',
|
'discovery',
|
||||||
'credentials',
|
'credentials',
|
||||||
|
'domains',
|
||||||
'endpoints',
|
'endpoints',
|
||||||
'groups',
|
'groups',
|
||||||
'limits',
|
'limits',
|
||||||
@ -57,6 +59,7 @@ __all__ = (
|
|||||||
__apis__ = (
|
__apis__ = (
|
||||||
discovery,
|
discovery,
|
||||||
credentials,
|
credentials,
|
||||||
|
domains,
|
||||||
endpoints,
|
endpoints,
|
||||||
groups,
|
groups,
|
||||||
limits,
|
limits,
|
||||||
|
556
keystone/api/domains.py
Normal file
556
keystone/api/domains.py
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
# This file handles all flask-restful resources for /v3/domains
|
||||||
|
|
||||||
|
import flask
|
||||||
|
import flask_restful
|
||||||
|
from six.moves import http_client
|
||||||
|
|
||||||
|
from keystone.common import json_home
|
||||||
|
from keystone.common import provider_api
|
||||||
|
from keystone.common import rbac_enforcer
|
||||||
|
from keystone.common import validation
|
||||||
|
import keystone.conf
|
||||||
|
from keystone import exception
|
||||||
|
from keystone.resource import schema
|
||||||
|
from keystone.server import flask as ks_flask
|
||||||
|
|
||||||
|
CONF = keystone.conf.CONF
|
||||||
|
ENFORCER = rbac_enforcer.RBACEnforcer
|
||||||
|
PROVIDERS = provider_api.ProviderAPIs
|
||||||
|
|
||||||
|
|
||||||
|
def _build_enforcement_target(allow_non_existing=False):
|
||||||
|
target = {}
|
||||||
|
if flask.request.view_args:
|
||||||
|
domain_id = flask.request.view_args.get('domain_id', None)
|
||||||
|
if domain_id:
|
||||||
|
target['domain'] = PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
|
||||||
|
role_id = flask.request.view_args.get('role_id', None)
|
||||||
|
if role_id:
|
||||||
|
target['role'] = PROVIDERS.role_api.get_role(role_id)
|
||||||
|
|
||||||
|
if flask.request.view_args.get('user_id'):
|
||||||
|
try:
|
||||||
|
target['user'] = PROVIDERS.identity_api.get_user(
|
||||||
|
flask.request.view_args['user_id'])
|
||||||
|
except exception.UserNotFound:
|
||||||
|
if not allow_non_existing:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
target['group'] = PROVIDERS.identity_api.get_group(
|
||||||
|
flask.request.view_args.get('group_id'))
|
||||||
|
except exception.GroupNotFound:
|
||||||
|
if not allow_non_existing:
|
||||||
|
raise
|
||||||
|
return target
|
||||||
|
|
||||||
|
|
||||||
|
class DomainResource(ks_flask.ResourceBase):
|
||||||
|
collection_key = 'domains'
|
||||||
|
member_key = 'domain'
|
||||||
|
get_member_from_driver = PROVIDERS.deferred_provider_lookup(
|
||||||
|
api='resource_api', method='get_domain')
|
||||||
|
|
||||||
|
def get(self, domain_id=None):
|
||||||
|
"""Get domain or list domains.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains
|
||||||
|
GET/HEAD /v3/domains/{domain_id}
|
||||||
|
"""
|
||||||
|
if domain_id is not None:
|
||||||
|
return self._get_domain(domain_id)
|
||||||
|
return self._list_domains()
|
||||||
|
|
||||||
|
def _get_domain(self, domain_id):
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain')
|
||||||
|
return self.wrap_member(PROVIDERS.resource_api.get_domain(domain_id))
|
||||||
|
|
||||||
|
def _list_domains(self):
|
||||||
|
filters = ['name', 'enabled']
|
||||||
|
ENFORCER.enforce_call(action='identity:list_domains',
|
||||||
|
filters=filters)
|
||||||
|
hints = self.build_driver_hints(filters)
|
||||||
|
refs = PROVIDERS.resource_api.list_domains(hints=hints)
|
||||||
|
return self.wrap_collection(refs, hints=hints)
|
||||||
|
|
||||||
|
def post(self):
|
||||||
|
"""Create domain.
|
||||||
|
|
||||||
|
POST /v3/domains
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:create_domain')
|
||||||
|
domain = self.request_body_json.get('domain', {})
|
||||||
|
validation.lazy_validate(schema.domain_create, domain)
|
||||||
|
domain = self._assign_unique_id(domain)
|
||||||
|
domain = self._normalize_dict(domain)
|
||||||
|
ref = PROVIDERS.resource_api.create_domain(
|
||||||
|
domain['id'], domain, initiator=self.audit_initiator)
|
||||||
|
return self.wrap_member(ref), http_client.CREATED
|
||||||
|
|
||||||
|
def patch(self, domain_id):
|
||||||
|
"""Update domain.
|
||||||
|
|
||||||
|
PATCH /v3/domains/{domain_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:update_domain')
|
||||||
|
domain = self.request_body_json.get('domain', {})
|
||||||
|
validation.lazy_validate(schema.domain_update, domain)
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
ref = PROVIDERS.resource_api.update_domain(
|
||||||
|
domain_id, domain, initiator=self.audit_initiator)
|
||||||
|
return self.wrap_member(ref)
|
||||||
|
|
||||||
|
def delete(self, domain_id):
|
||||||
|
"""Delete domain.
|
||||||
|
|
||||||
|
DELETE /v3/domains/{domain_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:delete_domain')
|
||||||
|
PROVIDERS.resource_api.delete_domain(
|
||||||
|
domain_id, initiator=self.audit_initiator)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class DomainConfigResource(ks_flask.ResourceBase):
|
||||||
|
member_key = 'config'
|
||||||
|
collection_key = 'config'
|
||||||
|
|
||||||
|
def get(self, domain_id=None):
|
||||||
|
"""Get domain config.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/config
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain_config')
|
||||||
|
config = PROVIDERS.domain_config_api.get_config(domain_id)
|
||||||
|
return {self.member_key: config}
|
||||||
|
|
||||||
|
def put(self, domain_id):
|
||||||
|
"""Create domain config.
|
||||||
|
|
||||||
|
POST /v3/domains/{domain_id}/config
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:create_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
config = self.request_body_json.get('config', {})
|
||||||
|
original_config = (
|
||||||
|
PROVIDERS.domain_config_api.get_config_with_sensitive_info(
|
||||||
|
domain_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ref = PROVIDERS.domain_config_api.create_config(domain_id, config)
|
||||||
|
if original_config:
|
||||||
|
return {self.member_key: ref}
|
||||||
|
else:
|
||||||
|
return {self.member_key: ref}, http_client.CREATED
|
||||||
|
|
||||||
|
def patch(self, domain_id=None):
|
||||||
|
"""Update domain config.
|
||||||
|
|
||||||
|
PATCH /v3/domains/{domain_id}/config
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:update_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
config = self.request_body_json.get('config', {})
|
||||||
|
ref = PROVIDERS.domain_config_api.update_config(domain_id, config)
|
||||||
|
return {self.member_key: ref}
|
||||||
|
|
||||||
|
def delete(self, domain_id=None):
|
||||||
|
"""Delete domain config.
|
||||||
|
|
||||||
|
DELETE /v3/domains/{domain_id}/config
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:delete_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
PROVIDERS.domain_config_api.delete_config(domain_id)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class DomainConfigGroupResource(ks_flask.ResourceBase):
|
||||||
|
member_key = 'config'
|
||||||
|
collection_key = 'config'
|
||||||
|
|
||||||
|
def get(self, domain_id=None, group=None):
|
||||||
|
"""Get domain config.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/config/{group}
|
||||||
|
"""
|
||||||
|
err = None
|
||||||
|
config = {}
|
||||||
|
try:
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
except Exception as e: # nosec
|
||||||
|
# We don't raise out here, we raise out after enforcement, this
|
||||||
|
# ensures we do not leak domain existance.
|
||||||
|
err = e
|
||||||
|
finally:
|
||||||
|
if group and group == 'security_compliance':
|
||||||
|
config = self._get_security_compliance_config(
|
||||||
|
domain_id, group)
|
||||||
|
else:
|
||||||
|
config = self._get_config(domain_id, group)
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
return {self.member_key: config}
|
||||||
|
|
||||||
|
def _get_config(self, domain_id, group):
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain_config')
|
||||||
|
return PROVIDERS.domain_config_api.get_config(domain_id, group)
|
||||||
|
|
||||||
|
def _get_security_compliance_config(self, domain_id, group):
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:get_security_compliance_domain_config')
|
||||||
|
return PROVIDERS.domain_config_api.get_security_compliance_config(
|
||||||
|
domain_id, group)
|
||||||
|
|
||||||
|
def patch(self, domain_id=None, group=None):
|
||||||
|
"""Update domain config.
|
||||||
|
|
||||||
|
PATCH /v3/domains/{domain_id}/config/{group}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:update_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
config = self.request_body_json.get('config', {})
|
||||||
|
ref = PROVIDERS.domain_config_api.update_config(
|
||||||
|
domain_id, config, group)
|
||||||
|
return {self.member_key: ref}
|
||||||
|
|
||||||
|
def delete(self, domain_id=None, group=None):
|
||||||
|
"""Delete domain config.
|
||||||
|
|
||||||
|
DELETE /v3/domains/{domain_id}/config/{group}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:delete_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
PROVIDERS.domain_config_api.delete_config(domain_id, group)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class DomainConfigOptionResource(ks_flask.ResourceBase):
|
||||||
|
member_key = 'config'
|
||||||
|
collection_key = 'config'
|
||||||
|
|
||||||
|
def get(self, domain_id=None, group=None, option=None):
|
||||||
|
"""Check if config option exists.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/config/{group}/{option}
|
||||||
|
"""
|
||||||
|
err = None
|
||||||
|
config = {}
|
||||||
|
try:
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
except Exception as e: # nosec
|
||||||
|
# We don't raise out here, we raise out after enforcement, this
|
||||||
|
# ensures we do not leak domain existance.
|
||||||
|
err = e
|
||||||
|
finally:
|
||||||
|
if group and group == 'security_compliance':
|
||||||
|
config = self._get_security_compliance_config(
|
||||||
|
domain_id, group, option)
|
||||||
|
else:
|
||||||
|
config = self._get_config(domain_id, group, option)
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
return {self.member_key: config}
|
||||||
|
|
||||||
|
def _get_config(self, domain_id, group, option):
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain_config')
|
||||||
|
return PROVIDERS.domain_config_api.get_config(
|
||||||
|
domain_id, group=group, option=option)
|
||||||
|
|
||||||
|
def _get_security_compliance_config(self, domain_id, group, option):
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:get_security_compliance_domain_config')
|
||||||
|
return PROVIDERS.domain_config_api.get_security_compliance_config(
|
||||||
|
domain_id, group, option=option)
|
||||||
|
|
||||||
|
def patch(self, domain_id=None, group=None, option=None):
|
||||||
|
"""Update domain config option.
|
||||||
|
|
||||||
|
PATCH /v3/domains/{domain_id}/config/{group}/{option}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:update_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
config = self.request_body_json.get('config', {})
|
||||||
|
ref = PROVIDERS.domain_config_api.update_config(
|
||||||
|
domain_id, config, group, option=option)
|
||||||
|
return {self.member_key: ref}
|
||||||
|
|
||||||
|
def delete(self, domain_id=None, group=None, option=None):
|
||||||
|
"""Delete domain config.
|
||||||
|
|
||||||
|
DELETE /v3/domains/{domain_id}/config/{group}/{option}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:delete_domain_config')
|
||||||
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
PROVIDERS.domain_config_api.delete_config(
|
||||||
|
domain_id, group, option=option)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultConfigResource(flask_restful.Resource):
|
||||||
|
def get(self):
|
||||||
|
"""Get default domain config.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/config/default
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain_config_default')
|
||||||
|
ref = PROVIDERS.domain_config_api.get_config_default()
|
||||||
|
return {'config': ref}
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultConfigGroupResource(flask_restful.Resource):
|
||||||
|
def get(self, group=None):
|
||||||
|
"""Get default domain group config.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/config/{group}/default
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain_config_default')
|
||||||
|
ref = PROVIDERS.domain_config_api.get_config_default(group=group)
|
||||||
|
return {'config': ref}
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultConfigOptionResource(flask_restful.Resource):
|
||||||
|
def get(self, group=None, option=None):
|
||||||
|
"""Get default domain group option config.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/config/{group}/{option}/default
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(action='identity:get_domain_config_default')
|
||||||
|
ref = PROVIDERS.domain_config_api.get_config_default(
|
||||||
|
group=group, option=option)
|
||||||
|
return {'config': ref}
|
||||||
|
|
||||||
|
|
||||||
|
class DomainUserListResource(flask_restful.Resource):
|
||||||
|
def get(self, domain_id=None, user_id=None):
|
||||||
|
"""Get user grant.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/users/{user_id}/roles
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:list_grants',
|
||||||
|
target_attr=_build_enforcement_target())
|
||||||
|
refs = PROVIDERS.assignment_api.list_grants(
|
||||||
|
domain_id=domain_id, user_id=user_id,
|
||||||
|
inherited_to_projects=False)
|
||||||
|
return ks_flask.ResourceBase.wrap_collection(
|
||||||
|
refs, collection_name='roles')
|
||||||
|
|
||||||
|
|
||||||
|
class DomainUserResource(ks_flask.ResourceBase):
|
||||||
|
member_key = 'grant'
|
||||||
|
collection_key = 'grants'
|
||||||
|
|
||||||
|
def get(self, domain_id=None, user_id=None, role_id=None):
|
||||||
|
"""Check if a user has a specific role on the domain.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/users/{user_id}/roles/{role_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:check_grant',
|
||||||
|
target_attr=_build_enforcement_target())
|
||||||
|
PROVIDERS.assignment_api.get_grant(
|
||||||
|
role_id, domain_id=domain_id, user_id=user_id,
|
||||||
|
inherited_to_projects=False)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def put(self, domain_id=None, user_id=None, role_id=None):
|
||||||
|
"""Create a role to a user on a domain.
|
||||||
|
|
||||||
|
PUT /v3/domains/{domain_id}/users/{user_id}/roles/{role_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:create_grant',
|
||||||
|
target_attr=_build_enforcement_target())
|
||||||
|
PROVIDERS.assignment_api.create_grant(
|
||||||
|
role_id, domain_id=domain_id, user_id=user_id,
|
||||||
|
inherited_to_projects=False, initiator=self.audit_initiator)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def delete(self, domain_id=None, user_id=None, role_id=None):
|
||||||
|
"""Revoke a role from user on a domain.
|
||||||
|
|
||||||
|
DELETE /v3/domains/{domain_id}/users/{user_id}/roles/{role_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:revoke_grant',
|
||||||
|
target_attr=_build_enforcement_target(allow_non_existing=True))
|
||||||
|
PROVIDERS.assignment_api.delete_grant(
|
||||||
|
role_id, domain_id=domain_id, user_id=user_id,
|
||||||
|
inherited_to_projects=False, initiator=self.audit_initiator)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class DomainGroupListResource(flask_restful.Resource):
|
||||||
|
def get(self, domain_id=None, group_id=None):
|
||||||
|
"""List all domain grats for a specific group.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/groups/{group_id}/roles
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:list_grants',
|
||||||
|
target_attr=_build_enforcement_target())
|
||||||
|
refs = PROVIDERS.assignment_api.list_grants(
|
||||||
|
domain_id=domain_id, group_id=group_id,
|
||||||
|
inherited_to_projects=False)
|
||||||
|
return ks_flask.ResourceBase.wrap_collection(
|
||||||
|
refs, collection_name='roles')
|
||||||
|
|
||||||
|
|
||||||
|
class DomainGroupResource(ks_flask.ResourceBase):
|
||||||
|
member_key = 'grant'
|
||||||
|
collection_key = 'grants'
|
||||||
|
|
||||||
|
def get(self, domain_id=None, group_id=None, role_id=None):
|
||||||
|
"""Check if a group has a specific role on a domain.
|
||||||
|
|
||||||
|
GET/HEAD /v3/domains/{domain_id}/groups/{group_id}/roles/{role_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:check_grant',
|
||||||
|
target_attr=_build_enforcement_target())
|
||||||
|
PROVIDERS.assignment_api.get_grant(
|
||||||
|
role_id, domain_id=domain_id, group_id=group_id,
|
||||||
|
inherited_to_projects=False)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def put(self, domain_id=None, group_id=None, role_id=None):
|
||||||
|
"""Grant a role to a group on a domain.
|
||||||
|
|
||||||
|
PUT /v3/domains/{domain_id}/groups/{group_id}/roles/{role_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:create_grant',
|
||||||
|
target_attr=_build_enforcement_target())
|
||||||
|
PROVIDERS.assignment_api.create_grant(
|
||||||
|
role_id, domain_id=domain_id, group_id=group_id,
|
||||||
|
inherited_to_projects=False, initiator=self.audit_initiator)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def delete(self, domain_id=None, group_id=None, role_id=None):
|
||||||
|
"""Revoke a role from a group on a domain.
|
||||||
|
|
||||||
|
DELETE /v3/domains/{domain_id}/groups/{group_id}/roles/{role_id}
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:revoke_grant',
|
||||||
|
target_attr=_build_enforcement_target(allow_non_existing=True))
|
||||||
|
PROVIDERS.assignment_api.delete_grant(
|
||||||
|
role_id, domain_id=domain_id, group_id=group_id,
|
||||||
|
inherited_to_projects=False, initiator=self.audit_initiator)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class DomainAPI(ks_flask.APIBase):
|
||||||
|
CONFIG_GROUP = json_home.build_v3_parameter_relation('config_group')
|
||||||
|
CONFIG_OPTION = json_home.build_v3_parameter_relation('config_option')
|
||||||
|
_name = 'domains'
|
||||||
|
_import_name = __name__
|
||||||
|
resources = [DomainResource]
|
||||||
|
resource_mapping = [
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainConfigResource,
|
||||||
|
url=('/domains/<string:domain_id>/config'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_config',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainConfigGroupResource,
|
||||||
|
url='/domains/<string:domain_id>/config/<string:group>',
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_config_group',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'group': CONFIG_GROUP}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainConfigOptionResource,
|
||||||
|
url=('/domains/<string:domain_id>/config/<string:group>'
|
||||||
|
'/<string:option>'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_config_option',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'group': CONFIG_GROUP,
|
||||||
|
'option': CONFIG_OPTION}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DefaultConfigResource,
|
||||||
|
url=('/domains/config/default'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_config_default',
|
||||||
|
path_vars={}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DefaultConfigGroupResource,
|
||||||
|
url='/domains/config/<string:group>/default',
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_config_default_group',
|
||||||
|
path_vars={
|
||||||
|
'group': CONFIG_GROUP}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DefaultConfigOptionResource,
|
||||||
|
url=('/domains/config/<string:group>'
|
||||||
|
'/<string:option>/default'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_config_default_option',
|
||||||
|
path_vars={
|
||||||
|
'group': CONFIG_GROUP,
|
||||||
|
'option': CONFIG_OPTION}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainUserListResource,
|
||||||
|
url=('/domains/<string:domain_id>/users'
|
||||||
|
'/<string:user_id>/roles'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_user_roles',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'user_id': json_home.Parameters.USER_ID,
|
||||||
|
}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainUserResource,
|
||||||
|
url=('/domains/<string:domain_id>/users'
|
||||||
|
'/<string:user_id>/roles/<string:role_id>'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_user_role',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'user_id': json_home.Parameters.USER_ID,
|
||||||
|
'role_id': json_home.Parameters.ROLE_ID
|
||||||
|
}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainGroupListResource,
|
||||||
|
url=('/domains/<string:domain_id>/groups'
|
||||||
|
'/<string:group_id>/roles'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_group_roles',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'group_id': json_home.Parameters.GROUP_ID,
|
||||||
|
}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=DomainGroupResource,
|
||||||
|
url=('/domains/<string:domain_id>/groups'
|
||||||
|
'/<string:group_id>/roles/<string:role_id>'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_group_role',
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'group_id': json_home.Parameters.GROUP_ID,
|
||||||
|
'role_id': json_home.Parameters.ROLE_ID
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
APIs = (DomainAPI,)
|
@ -285,7 +285,8 @@ class Manager(manager.Manager):
|
|||||||
@notifications.role_assignment('created')
|
@notifications.role_assignment('created')
|
||||||
def create_grant(self, role_id, user_id=None, group_id=None,
|
def create_grant(self, role_id, user_id=None, group_id=None,
|
||||||
domain_id=None, project_id=None,
|
domain_id=None, project_id=None,
|
||||||
inherited_to_projects=False, context=None):
|
inherited_to_projects=False, context=None,
|
||||||
|
initiator=None):
|
||||||
role = PROVIDERS.role_api.get_role(role_id)
|
role = PROVIDERS.role_api.get_role(role_id)
|
||||||
if domain_id:
|
if domain_id:
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
@ -335,7 +336,8 @@ class Manager(manager.Manager):
|
|||||||
@notifications.role_assignment('deleted')
|
@notifications.role_assignment('deleted')
|
||||||
def delete_grant(self, role_id, user_id=None, group_id=None,
|
def delete_grant(self, role_id, user_id=None, group_id=None,
|
||||||
domain_id=None, project_id=None,
|
domain_id=None, project_id=None,
|
||||||
inherited_to_projects=False, context=None):
|
inherited_to_projects=False, context=None,
|
||||||
|
initiator=None):
|
||||||
|
|
||||||
# check if role exist before any processing
|
# check if role exist before any processing
|
||||||
PROVIDERS.role_api.get_role(role_id)
|
PROVIDERS.role_api.get_role(role_id)
|
||||||
|
@ -31,7 +31,7 @@ class Public(wsgi.ComposableRouter):
|
|||||||
|
|
||||||
class Routers(wsgi.RoutersBase):
|
class Routers(wsgi.RoutersBase):
|
||||||
|
|
||||||
_path_prefixes = ('users', 'projects', 'domains')
|
_path_prefixes = ('users', 'projects')
|
||||||
|
|
||||||
def append_v3_routers(self, mapper, routers):
|
def append_v3_routers(self, mapper, routers):
|
||||||
|
|
||||||
@ -88,45 +88,3 @@ class Routers(wsgi.RoutersBase):
|
|||||||
'group_id': json_home.Parameters.GROUP_ID,
|
'group_id': json_home.Parameters.GROUP_ID,
|
||||||
'project_id': json_home.Parameters.PROJECT_ID,
|
'project_id': json_home.Parameters.PROJECT_ID,
|
||||||
})
|
})
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/domains/{domain_id}/users/{user_id}/roles/{role_id}',
|
|
||||||
get_head_action='check_grant',
|
|
||||||
put_action='create_grant',
|
|
||||||
delete_action='revoke_grant',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_user_role'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'role_id': json_home.Parameters.ROLE_ID,
|
|
||||||
'user_id': json_home.Parameters.USER_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/domains/{domain_id}/groups/{group_id}/roles/{role_id}',
|
|
||||||
get_head_action='check_grant',
|
|
||||||
put_action='create_grant',
|
|
||||||
delete_action='revoke_grant',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_group_role'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'group_id': json_home.Parameters.GROUP_ID,
|
|
||||||
'role_id': json_home.Parameters.ROLE_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/domains/{domain_id}/users/{user_id}/roles',
|
|
||||||
get_head_action='list_grants',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_user_roles'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'user_id': json_home.Parameters.USER_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/domains/{domain_id}/groups/{group_id}/roles',
|
|
||||||
get_head_action='list_grants',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_group_roles'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'group_id': json_home.Parameters.GROUP_ID,
|
|
||||||
})
|
|
||||||
|
@ -615,7 +615,14 @@ class CadfRoleAssignmentNotificationWrapper(object):
|
|||||||
inherited = call_args['inherited_to_projects']
|
inherited = call_args['inherited_to_projects']
|
||||||
context = call_args['context']
|
context = call_args['context']
|
||||||
|
|
||||||
|
# TODO(gagehugo): Once all of the APIs for grant creation
|
||||||
|
# and deletion are moved over to flask, get rid of checking
|
||||||
|
# context here and only grab the initiator from the
|
||||||
|
# passed in value
|
||||||
|
if context:
|
||||||
initiator = _get_request_audit_info(context)
|
initiator = _get_request_audit_info(context)
|
||||||
|
else:
|
||||||
|
initiator = call_args.get('initiator', None)
|
||||||
target = resource.Resource(typeURI=taxonomy.ACCOUNT_USER)
|
target = resource.Resource(typeURI=taxonomy.ACCOUNT_USER)
|
||||||
|
|
||||||
audit_kwargs = {}
|
audit_kwargs = {}
|
||||||
|
@ -39,118 +39,6 @@ class DomainV3(controller.V3Controller):
|
|||||||
super(DomainV3, self).__init__()
|
super(DomainV3, self).__init__()
|
||||||
self.get_member_from_driver = PROVIDERS.resource_api.get_domain
|
self.get_member_from_driver = PROVIDERS.resource_api.get_domain
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def create_domain(self, request, domain):
|
|
||||||
validation.lazy_validate(schema.domain_create, domain)
|
|
||||||
ref = self._assign_unique_id(self._normalize_dict(domain))
|
|
||||||
ref = PROVIDERS.resource_api.create_domain(
|
|
||||||
ref['id'], ref, initiator=request.audit_initiator
|
|
||||||
)
|
|
||||||
return DomainV3.wrap_member(request.context_dict, ref)
|
|
||||||
|
|
||||||
@controller.filterprotected('enabled', 'name')
|
|
||||||
def list_domains(self, request, filters):
|
|
||||||
hints = DomainV3.build_driver_hints(request, filters)
|
|
||||||
refs = PROVIDERS.resource_api.list_domains(hints=hints)
|
|
||||||
return DomainV3.wrap_collection(request.context_dict,
|
|
||||||
refs, hints=hints)
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def get_domain(self, request, domain_id):
|
|
||||||
ref = PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
return DomainV3.wrap_member(request.context_dict, ref)
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def update_domain(self, request, domain_id, domain):
|
|
||||||
validation.lazy_validate(schema.domain_update, domain)
|
|
||||||
self._require_matching_id(domain_id, domain)
|
|
||||||
ref = PROVIDERS.resource_api.update_domain(
|
|
||||||
domain_id, domain, initiator=request.audit_initiator
|
|
||||||
)
|
|
||||||
return DomainV3.wrap_member(request.context_dict, ref)
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def delete_domain(self, request, domain_id):
|
|
||||||
return PROVIDERS.resource_api.delete_domain(
|
|
||||||
domain_id, initiator=request.audit_initiator
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DomainConfigV3(controller.V3Controller):
|
|
||||||
member_name = 'config'
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def create_domain_config(self, request, domain_id, config):
|
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
original_config = (
|
|
||||||
PROVIDERS.domain_config_api.get_config_with_sensitive_info(
|
|
||||||
domain_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
ref = PROVIDERS.domain_config_api.create_config(domain_id, config)
|
|
||||||
if original_config:
|
|
||||||
# Return status code 200, since config already existed
|
|
||||||
return wsgi.render_response(body={self.member_name: ref})
|
|
||||||
else:
|
|
||||||
return wsgi.render_response(
|
|
||||||
body={self.member_name: ref},
|
|
||||||
status=(http_client.CREATED,
|
|
||||||
http_client.responses[http_client.CREATED]))
|
|
||||||
|
|
||||||
def get_domain_config_wrapper(self, request, domain_id, group=None,
|
|
||||||
option=None):
|
|
||||||
if group and group == 'security_compliance':
|
|
||||||
return self.get_security_compliance_domain_config(
|
|
||||||
request, domain_id, group=group, option=option
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return self.get_domain_config(
|
|
||||||
request, domain_id, group=group, option=option
|
|
||||||
)
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def get_security_compliance_domain_config(self, request, domain_id,
|
|
||||||
group=None, option=None):
|
|
||||||
ref = PROVIDERS.domain_config_api.get_security_compliance_config(
|
|
||||||
domain_id, group, option=option
|
|
||||||
)
|
|
||||||
return {self.member_name: ref}
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def get_domain_config(self, request, domain_id, group=None, option=None):
|
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
ref = PROVIDERS.domain_config_api.get_config(domain_id, group, option)
|
|
||||||
return {self.member_name: ref}
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def update_domain_config(
|
|
||||||
self, request, domain_id, config, group, option):
|
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
ref = PROVIDERS.domain_config_api.update_config(
|
|
||||||
domain_id, config, group, option)
|
|
||||||
return wsgi.render_response(body={self.member_name: ref})
|
|
||||||
|
|
||||||
def update_domain_config_group(self, context, domain_id, group, config):
|
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
return self.update_domain_config(
|
|
||||||
context, domain_id, config, group, option=None)
|
|
||||||
|
|
||||||
def update_domain_config_only(self, context, domain_id, config):
|
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
return self.update_domain_config(
|
|
||||||
context, domain_id, config, group=None, option=None)
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def delete_domain_config(
|
|
||||||
self, request, domain_id, group=None, option=None):
|
|
||||||
PROVIDERS.resource_api.get_domain(domain_id)
|
|
||||||
PROVIDERS.domain_config_api.delete_config(domain_id, group, option)
|
|
||||||
|
|
||||||
@controller.protected()
|
|
||||||
def get_domain_config_default(self, request, group=None, option=None):
|
|
||||||
ref = PROVIDERS.domain_config_api.get_config_default(group, option)
|
|
||||||
return {self.member_name: ref}
|
|
||||||
|
|
||||||
|
|
||||||
class ProjectV3(controller.V3Controller):
|
class ProjectV3(controller.V3Controller):
|
||||||
collection_name = 'projects'
|
collection_name = 'projects'
|
||||||
|
@ -23,85 +23,11 @@ from keystone.resource import controllers
|
|||||||
|
|
||||||
class Routers(wsgi.RoutersBase):
|
class Routers(wsgi.RoutersBase):
|
||||||
|
|
||||||
_path_prefixes = ('domains', 'projects')
|
_path_prefixes = ('projects')
|
||||||
|
|
||||||
def append_v3_routers(self, mapper, routers):
|
def append_v3_routers(self, mapper, routers):
|
||||||
routers.append(
|
|
||||||
router.Router(controllers.DomainV3(),
|
|
||||||
'domains', 'domain',
|
|
||||||
resource_descriptions=self.v3_resources))
|
|
||||||
|
|
||||||
config_controller = controllers.DomainConfigV3()
|
|
||||||
tag_controller = controllers.ProjectTagV3()
|
tag_controller = controllers.ProjectTagV3()
|
||||||
|
|
||||||
self._add_resource(
|
|
||||||
mapper, config_controller,
|
|
||||||
path='/domains/{domain_id}/config',
|
|
||||||
get_head_action='get_domain_config',
|
|
||||||
put_action='create_domain_config',
|
|
||||||
patch_action='update_domain_config_only',
|
|
||||||
delete_action='delete_domain_config',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_config'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID
|
|
||||||
})
|
|
||||||
|
|
||||||
config_group_param = (
|
|
||||||
json_home.build_v3_parameter_relation('config_group'))
|
|
||||||
self._add_resource(
|
|
||||||
mapper, config_controller,
|
|
||||||
path='/domains/{domain_id}/config/{group}',
|
|
||||||
get_head_action='get_domain_config_wrapper',
|
|
||||||
patch_action='update_domain_config_group',
|
|
||||||
delete_action='delete_domain_config',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_config_group'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'group': config_group_param
|
|
||||||
})
|
|
||||||
|
|
||||||
self._add_resource(
|
|
||||||
mapper, config_controller,
|
|
||||||
path='/domains/{domain_id}/config/{group}/{option}',
|
|
||||||
get_head_action='get_domain_config_wrapper',
|
|
||||||
patch_action='update_domain_config',
|
|
||||||
delete_action='delete_domain_config',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_config_option'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'group': config_group_param,
|
|
||||||
'option': json_home.build_v3_parameter_relation(
|
|
||||||
'config_option')
|
|
||||||
})
|
|
||||||
|
|
||||||
self._add_resource(
|
|
||||||
mapper, config_controller,
|
|
||||||
path='/domains/config/default',
|
|
||||||
get_head_action='get_domain_config_default',
|
|
||||||
rel=json_home.build_v3_resource_relation('domain_config_default'))
|
|
||||||
|
|
||||||
self._add_resource(
|
|
||||||
mapper, config_controller,
|
|
||||||
path='/domains/config/{group}/default',
|
|
||||||
get_head_action='get_domain_config_default',
|
|
||||||
rel=json_home.build_v3_resource_relation(
|
|
||||||
'domain_config_default_group'),
|
|
||||||
path_vars={
|
|
||||||
'group': config_group_param
|
|
||||||
})
|
|
||||||
|
|
||||||
self._add_resource(
|
|
||||||
mapper, config_controller,
|
|
||||||
path='/domains/config/{group}/{option}/default',
|
|
||||||
get_head_action='get_domain_config_default',
|
|
||||||
rel=json_home.build_v3_resource_relation(
|
|
||||||
'domain_config_default_option'),
|
|
||||||
path_vars={
|
|
||||||
'group': config_group_param,
|
|
||||||
'option': json_home.build_v3_parameter_relation(
|
|
||||||
'config_option')
|
|
||||||
})
|
|
||||||
|
|
||||||
routers.append(
|
routers.append(
|
||||||
router.Router(controllers.ProjectV3(),
|
router.Router(controllers.ProjectV3(),
|
||||||
'projects', 'project',
|
'projects', 'project',
|
||||||
|
@ -39,6 +39,7 @@ from keystone.resource import routers as resource_routers
|
|||||||
# support is removed.
|
# support is removed.
|
||||||
_MOVED_API_PREFIXES = frozenset(
|
_MOVED_API_PREFIXES = frozenset(
|
||||||
['credentials',
|
['credentials',
|
||||||
|
'domains',
|
||||||
'endpoints',
|
'endpoints',
|
||||||
'groups',
|
'groups',
|
||||||
'OS-EP-FILTER',
|
'OS-EP-FILTER',
|
||||||
|
Loading…
Reference in New Issue
Block a user