Support enables rbac policies new defaults
The Magnum service allow enables policies (RBAC) new defaults and scope by default. The Default value of config options ``[oslo_policy] enforce_scope`` and ``[oslo_policy] oslo_policy.enforce_new_defaults`` are both to ``False``, but will change to ``True`` in following cycles. To enable them then modify the below config options value in ``magnum.conf`` file:: [oslo_policy] enforce_new_defaults=True enforce_scope=True reference tc goal for more detail: https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html Related blueprint secure-rbac Change-Id: I249942a355577c4f1ef51b3988f0cc4979959d0b
This commit is contained in:
parent
fda54620ad
commit
5971243169
|
@ -153,6 +153,14 @@ function create_magnum_conf {
|
||||||
|
|
||||||
iniset $MAGNUM_CONF oslo_policy policy_file $MAGNUM_POLICY
|
iniset $MAGNUM_CONF oslo_policy policy_file $MAGNUM_POLICY
|
||||||
|
|
||||||
|
if [[ "$MAGNUM_ENFORCE_SCOPE" == True ]] ; then
|
||||||
|
iniset $MAGNUM_CONF oslo_policy enforce_scope true
|
||||||
|
iniset $MAGNUM_CONF oslo_policy enforce_new_defaults true
|
||||||
|
else
|
||||||
|
iniset $MAGNUM_CONF oslo_policy enforce_scope false
|
||||||
|
iniset $MAGNUM_CONF oslo_policy enforce_new_defaults false
|
||||||
|
fi
|
||||||
|
|
||||||
iniset $MAGNUM_CONF keystone_auth auth_type password
|
iniset $MAGNUM_CONF keystone_auth auth_type password
|
||||||
iniset $MAGNUM_CONF keystone_auth username magnum
|
iniset $MAGNUM_CONF keystone_auth username magnum
|
||||||
iniset $MAGNUM_CONF keystone_auth password $SERVICE_PASSWORD
|
iniset $MAGNUM_CONF keystone_auth password $SERVICE_PASSWORD
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
# PHYSICAL_NETWORK=public
|
# PHYSICAL_NETWORK=public
|
||||||
# OVS_PHYSICAL_BRIDGE=br-ex
|
# OVS_PHYSICAL_BRIDGE=br-ex
|
||||||
|
|
||||||
|
# This option controls whether or not to enforce scope when evaluating policies. Learn more:
|
||||||
|
# https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_scope
|
||||||
|
MAGNUM_ENFORCE_SCOPE=$(trueorfalse False MAGNUM_ENFORCE_SCOPE)
|
||||||
|
|
||||||
# Enable Magnum services
|
# Enable Magnum services
|
||||||
enable_service magnum-api
|
enable_service magnum-api
|
||||||
enable_service magnum-cond
|
enable_service magnum-cond
|
||||||
|
|
|
@ -52,8 +52,8 @@ class ContextHook(hooks.PecanHook):
|
||||||
user_id = headers.get('X-User-Id')
|
user_id = headers.get('X-User-Id')
|
||||||
project = headers.get('X-Project-Name')
|
project = headers.get('X-Project-Name')
|
||||||
project_id = headers.get('X-Project-Id')
|
project_id = headers.get('X-Project-Id')
|
||||||
domain_id = headers.get('X-User-Domain-Id')
|
user_domain_id = headers.get('X-User-Domain-Id')
|
||||||
domain_name = headers.get('X-User-Domain-Name')
|
user_domain_name = headers.get('X-User-Domain-Name')
|
||||||
auth_token = headers.get('X-Auth-Token')
|
auth_token = headers.get('X-Auth-Token')
|
||||||
roles = headers.get('X-Roles', '').split(',')
|
roles = headers.get('X-Roles', '').split(',')
|
||||||
auth_token_info = state.request.environ.get('keystone.token_info')
|
auth_token_info = state.request.environ.get('keystone.token_info')
|
||||||
|
@ -72,8 +72,8 @@ class ContextHook(hooks.PecanHook):
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
project_name=project,
|
project_name=project,
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
domain_id=domain_id,
|
user_domain_id=user_domain_id,
|
||||||
domain_name=domain_name,
|
user_domain_name=user_domain_name,
|
||||||
roles=roles)
|
roles=roles)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class RequestContext(context.RequestContext):
|
||||||
"""
|
"""
|
||||||
super(RequestContext, self).__init__(auth_token=auth_token,
|
super(RequestContext, self).__init__(auth_token=auth_token,
|
||||||
user_id=user_name,
|
user_id=user_name,
|
||||||
project_id=project_name,
|
project_id=project_id,
|
||||||
is_admin=is_admin,
|
is_admin=is_admin,
|
||||||
read_only=read_only,
|
read_only=read_only,
|
||||||
show_deleted=show_deleted,
|
show_deleted=show_deleted,
|
||||||
|
@ -53,8 +53,6 @@ class RequestContext(context.RequestContext):
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.project_name = project_name
|
self.project_name = project_name
|
||||||
self.project_id = project_id
|
self.project_id = project_id
|
||||||
self.domain_id = domain_id
|
|
||||||
self.domain_name = domain_name
|
|
||||||
self.user_domain_id = user_domain_id
|
self.user_domain_id = user_domain_id
|
||||||
self.user_domain_name = user_domain_name
|
self.user_domain_name = user_domain_name
|
||||||
self.auth_url = auth_url
|
self.auth_url = auth_url
|
||||||
|
@ -71,8 +69,6 @@ class RequestContext(context.RequestContext):
|
||||||
value = super(RequestContext, self).to_dict()
|
value = super(RequestContext, self).to_dict()
|
||||||
value.update({'auth_token': self.auth_token,
|
value.update({'auth_token': self.auth_token,
|
||||||
'auth_url': self.auth_url,
|
'auth_url': self.auth_url,
|
||||||
'domain_id': self.domain_id,
|
|
||||||
'domain_name': self.domain_name,
|
|
||||||
'user_domain_id': self.user_domain_id,
|
'user_domain_id': self.user_domain_id,
|
||||||
'user_domain_name': self.user_domain_name,
|
'user_domain_name': self.user_domain_name,
|
||||||
'user_name': self.user_name,
|
'user_name': self.user_name,
|
||||||
|
|
|
@ -13,12 +13,79 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
from oslo_policy import policy
|
from oslo_policy import policy
|
||||||
|
|
||||||
ROLE_ADMIN = 'rule:context_is_admin'
|
|
||||||
RULE_ADMIN_OR_OWNER = 'rule:admin_or_owner'
|
RULE_ADMIN_OR_OWNER = 'rule:admin_or_owner'
|
||||||
RULE_ADMIN_API = 'rule:admin_api'
|
RULE_ADMIN_API = 'rule:context_is_admin'
|
||||||
RULE_ADMIN_OR_USER = 'rule:admin_or_user'
|
RULE_ADMIN_OR_USER = 'rule:admin_or_user'
|
||||||
RULE_CLUSTER_USER = 'rule:cluster_user'
|
RULE_CLUSTER_USER = 'rule:cluster_user'
|
||||||
RULE_DENY_CLUSTER_USER = 'rule:deny_cluster_user'
|
RULE_DENY_CLUSTER_USER = 'rule:deny_cluster_user'
|
||||||
|
RULE_USER = "rule:is_user"
|
||||||
|
# Generic check string for checking if a user is authorized on a particular
|
||||||
|
# project, specifically with the member role.
|
||||||
|
RULE_PROJECT_MEMBER = 'rule:project_member'
|
||||||
|
# Generic check string for checking if a user is authorized on a particular
|
||||||
|
# project but with read-only access. For example, this persona would be able to
|
||||||
|
# list private images owned by a project but cannot make any writeable changes
|
||||||
|
# to those images.
|
||||||
|
RULE_PROJECT_READER = 'rule:project_reader'
|
||||||
|
|
||||||
|
RULE_USER_OR_CLUSTER_USER = (
|
||||||
|
'rule:user_or_cluster_user')
|
||||||
|
RULE_ADMIN_OR_PROJECT_READER = (
|
||||||
|
'rule:admin_or_project_reader')
|
||||||
|
RULE_ADMIN_OR_PROJECT_MEMBER = (
|
||||||
|
'rule:admin_or_project_member')
|
||||||
|
RULE_ADMIN_OR_PROJECT_MEMBER_USER = (
|
||||||
|
'rule:admin_or_project_member_user')
|
||||||
|
RULE_ADMIN_OR_PROJECT_MEMBER_USER_OR_CLUSTER_USER = (
|
||||||
|
'rule:admin_or_project_member_user_or_cluster_user')
|
||||||
|
RULE_PROJECT_MEMBER_DENY_CLUSTER_USER = (
|
||||||
|
'rule:project_member_deny_cluster_user')
|
||||||
|
RULE_ADMIN_OR_PROJECT_MEMBER_DENY_CLUSTER_USER = (
|
||||||
|
'rule:admin_or_project_member_deny_cluster_user')
|
||||||
|
RULE_PROJECT_READER_DENY_CLUSTER_USER = (
|
||||||
|
'rule:project_reader_deny_cluster_user')
|
||||||
|
RULE_ADMIN_OR_PROJECT_READER_DENY_CLUSTER_USER = (
|
||||||
|
'rule:admin_or_project_reader_deny_cluster_user')
|
||||||
|
RULE_ADMIN_OR_PROJECT_READER_USER_OR_CLUSTER_USER = (
|
||||||
|
'rule:admin_or_project_reader_user_or_cluster_user')
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Deprecated Since OpenStack 2023.2(Magnum 17.0.0) and should be removed in
|
||||||
|
# The following cycle.
|
||||||
|
|
||||||
|
DEPRECATED_REASON = """
|
||||||
|
The Magnum API now enforces scoped tokens and default reader and member roles.
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEPRECATED_SINCE = 'OpenStack 2023.2(Magnum 17.0.0)'
|
||||||
|
|
||||||
|
|
||||||
|
DEPRECATED_DENY_CLUSTER_USER = policy.DeprecatedRule(
|
||||||
|
name=RULE_DENY_CLUSTER_USER,
|
||||||
|
check_str='not domain_id:%(trustee_domain_id)s',
|
||||||
|
deprecated_reason=DEPRECATED_REASON,
|
||||||
|
deprecated_since=DEPRECATED_SINCE
|
||||||
|
)
|
||||||
|
|
||||||
|
DEPRECATED_RULE_ADMIN_OR_OWNER = policy.DeprecatedRule(
|
||||||
|
name=RULE_ADMIN_OR_OWNER,
|
||||||
|
check_str='is_admin:True or project_id:%(project_id)s',
|
||||||
|
deprecated_reason=DEPRECATED_REASON,
|
||||||
|
deprecated_since=DEPRECATED_SINCE
|
||||||
|
)
|
||||||
|
|
||||||
|
# Only used for DEPRECATED_RULE_ADMIN_OR_USER_OR_CLUSTER_USER
|
||||||
|
RULE_ADMIN_OR_USER_OR_CLUSTER_USER = (
|
||||||
|
'rule:admin_or_user_or_cluster_user')
|
||||||
|
|
||||||
|
DEPRECATED_RULE_ADMIN_OR_USER_OR_CLUSTER_USER = policy.DeprecatedRule(
|
||||||
|
name=RULE_ADMIN_OR_USER_OR_CLUSTER_USER,
|
||||||
|
check_str=f"(({RULE_ADMIN_API}) or ({RULE_USER_OR_CLUSTER_USER}))",
|
||||||
|
deprecated_reason=DEPRECATED_REASON,
|
||||||
|
deprecated_since=DEPRECATED_SINCE
|
||||||
|
)
|
||||||
|
# ==========================================================
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
policy.RuleDefault(
|
policy.RuleDefault(
|
||||||
|
@ -29,14 +96,14 @@ rules = [
|
||||||
name='admin_or_owner',
|
name='admin_or_owner',
|
||||||
check_str='is_admin:True or project_id:%(project_id)s'
|
check_str='is_admin:True or project_id:%(project_id)s'
|
||||||
),
|
),
|
||||||
policy.RuleDefault(
|
|
||||||
name='admin_api',
|
|
||||||
check_str='rule:context_is_admin'
|
|
||||||
),
|
|
||||||
policy.RuleDefault(
|
policy.RuleDefault(
|
||||||
name='admin_or_user',
|
name='admin_or_user',
|
||||||
check_str='is_admin:True or user_id:%(user_id)s'
|
check_str='is_admin:True or user_id:%(user_id)s'
|
||||||
),
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='is_user',
|
||||||
|
check_str='user_id:%(user_id)s'
|
||||||
|
),
|
||||||
policy.RuleDefault(
|
policy.RuleDefault(
|
||||||
name='cluster_user',
|
name='cluster_user',
|
||||||
check_str='user_id:%(trustee_user_id)s'
|
check_str='user_id:%(trustee_user_id)s'
|
||||||
|
@ -44,7 +111,93 @@ rules = [
|
||||||
policy.RuleDefault(
|
policy.RuleDefault(
|
||||||
name='deny_cluster_user',
|
name='deny_cluster_user',
|
||||||
check_str='not domain_id:%(trustee_domain_id)s'
|
check_str='not domain_id:%(trustee_domain_id)s'
|
||||||
)
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='project_member',
|
||||||
|
check_str='role:member and project_id:%(project_id)s'
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='project_reader',
|
||||||
|
check_str='role:reader and project_id:%(project_id)s'
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_reader',
|
||||||
|
check_str=f"({RULE_ADMIN_API}) or ({RULE_PROJECT_READER})",
|
||||||
|
deprecated_rule=DEPRECATED_RULE_ADMIN_OR_OWNER
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_member',
|
||||||
|
check_str=f"({RULE_ADMIN_API}) or ({RULE_PROJECT_MEMBER})",
|
||||||
|
deprecated_rule=DEPRECATED_RULE_ADMIN_OR_OWNER
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_member_user',
|
||||||
|
check_str=(
|
||||||
|
f"({RULE_ADMIN_API}) or (({RULE_PROJECT_MEMBER}) and "
|
||||||
|
f"({RULE_USER}))"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='user_or_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"(({RULE_USER}) or ({RULE_CLUSTER_USER}))"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_user_or_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"(({RULE_ADMIN_API}) or ({RULE_USER_OR_CLUSTER_USER}))"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_member_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"({RULE_ADMIN_API}) or (({RULE_PROJECT_MEMBER}) "
|
||||||
|
f"and ({RULE_CLUSTER_USER}))"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_member_user_or_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"({RULE_ADMIN_API}) or (({RULE_PROJECT_MEMBER}) and "
|
||||||
|
f"({RULE_USER_OR_CLUSTER_USER}))"
|
||||||
|
),
|
||||||
|
deprecated_rule=DEPRECATED_RULE_ADMIN_OR_USER_OR_CLUSTER_USER
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='project_member_deny_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"(({RULE_PROJECT_MEMBER}) and ({RULE_DENY_CLUSTER_USER}))"
|
||||||
|
),
|
||||||
|
deprecated_rule=DEPRECATED_DENY_CLUSTER_USER
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_member_deny_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"({RULE_ADMIN_API}) or ({RULE_PROJECT_MEMBER_DENY_CLUSTER_USER})"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='project_reader_deny_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"(({RULE_PROJECT_READER}) and ({RULE_DENY_CLUSTER_USER}))"
|
||||||
|
),
|
||||||
|
deprecated_rule=DEPRECATED_DENY_CLUSTER_USER
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_reader_deny_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"({RULE_ADMIN_API}) or ({RULE_PROJECT_READER_DENY_CLUSTER_USER})"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name='admin_or_project_reader_user_or_cluster_user',
|
||||||
|
check_str=(
|
||||||
|
f"({RULE_ADMIN_API}) or (({RULE_PROJECT_READER}) and "
|
||||||
|
f"({RULE_USER_OR_CLUSTER_USER}))"
|
||||||
|
),
|
||||||
|
deprecated_rule=DEPRECATED_RULE_ADMIN_OR_USER_OR_CLUSTER_USER
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,12 @@ from oslo_policy import policy
|
||||||
from magnum.common.policies import base
|
from magnum.common.policies import base
|
||||||
|
|
||||||
CERTIFICATE = 'certificate:%s'
|
CERTIFICATE = 'certificate:%s'
|
||||||
RULE_ADMIN_OR_USER_OR_CLUSTER_USER = base.RULE_ADMIN_OR_USER + " or " + \
|
|
||||||
base.RULE_CLUSTER_USER
|
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CERTIFICATE % 'create',
|
name=CERTIFICATE % 'create',
|
||||||
check_str=RULE_ADMIN_OR_USER_OR_CLUSTER_USER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER_USER_OR_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Sign a new certificate by the CA.',
|
description='Sign a new certificate by the CA.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -33,7 +32,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CERTIFICATE % 'get',
|
name=CERTIFICATE % 'get',
|
||||||
check_str=RULE_ADMIN_OR_USER_OR_CLUSTER_USER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_READER_USER_OR_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve CA information about the given cluster.',
|
description='Retrieve CA information about the given cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CERTIFICATE % 'rotate_ca',
|
name=CERTIFICATE % 'rotate_ca',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Rotate the CA certificate on the given cluster.',
|
description='Rotate the CA certificate on the given cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,8 @@ CLUSTER = 'cluster:%s'
|
||||||
rules = [
|
rules = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'create',
|
name=CLUSTER % 'create',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Create a new cluster.',
|
description='Create a new cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -31,7 +32,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'delete',
|
name=CLUSTER % 'delete',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Delete a cluster.',
|
description='Delete a cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -53,7 +55,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'detail',
|
name=CLUSTER % 'detail',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of clusters with detail.',
|
description='Retrieve a list of clusters with detail.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -75,7 +78,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'get',
|
name=CLUSTER % 'get',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve information about the given cluster.',
|
description='Retrieve information about the given cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -98,7 +102,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'get_all',
|
name=CLUSTER % 'get_all',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of clusters.',
|
description='Retrieve a list of clusters.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -120,7 +125,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'update',
|
name=CLUSTER % 'update',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Update an existing cluster.',
|
description='Update an existing cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -131,7 +137,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'update_health_status',
|
name=CLUSTER % 'update_health_status',
|
||||||
check_str=base.RULE_ADMIN_OR_USER + " or " + base.RULE_CLUSTER_USER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER_USER_OR_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Update the health status of an existing cluster.',
|
description='Update the health status of an existing cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -153,7 +160,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'resize',
|
name=CLUSTER % 'resize',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Resize an existing cluster.',
|
description='Resize an existing cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -164,7 +172,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER % 'upgrade',
|
name=CLUSTER % 'upgrade',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Upgrade an existing cluster.',
|
description='Upgrade an existing cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,18 +20,20 @@ CLUSTER_TEMPLATE = 'clustertemplate:%s'
|
||||||
rules = [
|
rules = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER_TEMPLATE % 'create',
|
name=CLUSTER_TEMPLATE % 'create',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Create a new cluster template.',
|
description='Create a new cluster template.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
'path': '/v1/clustertemplates',
|
'path': '/v1/clustertemplates',
|
||||||
'method': 'POST'
|
'method': 'POST'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER_TEMPLATE % 'delete',
|
name=CLUSTER_TEMPLATE % 'delete',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Delete a cluster template.',
|
description='Delete a cluster template.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -65,7 +67,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER_TEMPLATE % 'detail',
|
name=CLUSTER_TEMPLATE % 'detail',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of cluster templates with detail.',
|
description='Retrieve a list of cluster templates with detail.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -76,7 +79,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER_TEMPLATE % 'get',
|
name=CLUSTER_TEMPLATE % 'get',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve information about the given cluster template.',
|
description='Retrieve information about the given cluster template.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -99,7 +103,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER_TEMPLATE % 'get_all',
|
name=CLUSTER_TEMPLATE % 'get_all',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of cluster templates.',
|
description='Retrieve a list of cluster templates.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -121,7 +126,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CLUSTER_TEMPLATE % 'update',
|
name=CLUSTER_TEMPLATE % 'update',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Update an existing cluster template.',
|
description='Update an existing cluster template.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,8 @@ FEDERATION = 'federation:%s'
|
||||||
rules = [
|
rules = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=FEDERATION % 'create',
|
name=FEDERATION % 'create',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Create a new federation.',
|
description='Create a new federation.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -31,7 +32,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=FEDERATION % 'delete',
|
name=FEDERATION % 'delete',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Delete a federation.',
|
description='Delete a federation.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -42,7 +44,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=FEDERATION % 'detail',
|
name=FEDERATION % 'detail',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of federations with detail.',
|
description='Retrieve a list of federations with detail.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -53,7 +56,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=FEDERATION % 'get',
|
name=FEDERATION % 'get',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve information about the given federation.',
|
description='Retrieve information about the given federation.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -64,7 +68,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=FEDERATION % 'get_all',
|
name=FEDERATION % 'get_all',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_READER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of federations.',
|
description='Retrieve a list of federations.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -75,7 +80,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=FEDERATION % 'update',
|
name=FEDERATION % 'update',
|
||||||
check_str=base.RULE_DENY_CLUSTER_USER,
|
check_str=base.RULE_PROJECT_MEMBER_DENY_CLUSTER_USER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Update an existing federation.',
|
description='Update an existing federation.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,8 @@ NODEGROUP = 'nodegroup:%s'
|
||||||
rules = [
|
rules = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=NODEGROUP % 'get',
|
name=NODEGROUP % 'get',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_READER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve information about the given nodegroup.',
|
description='Retrieve information about the given nodegroup.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=NODEGROUP % 'get_all',
|
name=NODEGROUP % 'get_all',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_READER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve a list of nodegroups that belong to a cluster.',
|
description='Retrieve a list of nodegroups that belong to a cluster.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -68,7 +70,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=NODEGROUP % 'create',
|
name=NODEGROUP % 'create',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Create a new nodegroup.',
|
description='Create a new nodegroup.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -79,7 +82,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=NODEGROUP % 'delete',
|
name=NODEGROUP % 'delete',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Delete a nodegroup.',
|
description='Delete a nodegroup.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
@ -90,7 +94,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=NODEGROUP % 'update',
|
name=NODEGROUP % 'update',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_MEMBER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Update an existing nodegroup.',
|
description='Update an existing nodegroup.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,8 @@ rules = [
|
||||||
),
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=QUOTA % 'get',
|
name=QUOTA % 'get',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_READER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve Quota information for the given project_id.',
|
description='Retrieve Quota information for the given project_id.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,8 @@ STATS = 'stats:%s'
|
||||||
rules = [
|
rules = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=STATS % 'get_all',
|
name=STATS % 'get_all',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_PROJECT_READER,
|
||||||
|
scope_types=["project"],
|
||||||
description='Retrieve magnum stats.',
|
description='Retrieve magnum stats.',
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
import decorator
|
import decorator
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
from oslo_policy import opts
|
from oslo_policy import opts
|
||||||
from oslo_policy import policy
|
from oslo_policy import policy
|
||||||
from oslo_utils import importutils
|
from oslo_utils import importutils
|
||||||
|
@ -27,6 +28,7 @@ from magnum.common import exception
|
||||||
from magnum.common import policies
|
from magnum.common import policies
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
_ENFORCER = None
|
_ENFORCER = None
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
@ -105,8 +107,14 @@ def enforce(context, rule=None, target=None,
|
||||||
target = {'project_id': context.project_id,
|
target = {'project_id': context.project_id,
|
||||||
'user_id': context.user_id}
|
'user_id': context.user_id}
|
||||||
add_policy_attributes(target)
|
add_policy_attributes(target)
|
||||||
return enforcer.enforce(rule, target, credentials,
|
|
||||||
do_raise=do_raise, exc=exc, *args, **kwargs)
|
try:
|
||||||
|
result = enforcer.enforce(rule, target, credentials,
|
||||||
|
do_raise=do_raise, exc=exc, *args, **kwargs)
|
||||||
|
except policy.InvalidScope as ex:
|
||||||
|
LOG.debug(f"Invalid scope while enforce policy :{str(ex)}")
|
||||||
|
raise exc(action=rule)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def add_policy_attributes(target):
|
def add_policy_attributes(target):
|
||||||
|
|
|
@ -25,7 +25,7 @@ fakeAuthTokenHeaders = {'X-User-Id': u'773a902f022949619b5c2f32cd89d419',
|
||||||
'X-Roles': 'role1,role2',
|
'X-Roles': 'role1,role2',
|
||||||
'X-Auth-Url': 'fake_auth_url',
|
'X-Auth-Url': 'fake_auth_url',
|
||||||
'X-Identity-Status': 'Confirmed',
|
'X-Identity-Status': 'Confirmed',
|
||||||
'X-User-Domain-Name': 'domain',
|
'X-User-Domain-Name': 'user_domain_name',
|
||||||
'X-Project-Domain-Id': 'project_domain_id',
|
'X-Project-Domain-Id': 'project_domain_id',
|
||||||
'X-User-Domain-Id': 'user_domain_id',
|
'X-User-Domain-Id': 'user_domain_id',
|
||||||
'OpenStack-API-Version': 'container-infra 1.0'
|
'OpenStack-API-Version': 'container-infra 1.0'
|
||||||
|
|
|
@ -128,6 +128,9 @@ class FunctionalTest(base.DbTestCase):
|
||||||
with the request
|
with the request
|
||||||
:param status: expected status code of response
|
:param status: expected status code of response
|
||||||
"""
|
"""
|
||||||
|
# Provide member role for put request
|
||||||
|
if not headers:
|
||||||
|
headers = {"X-Roles": "member"}
|
||||||
return self._request_json(path=path, params=params,
|
return self._request_json(path=path, params=params,
|
||||||
expect_errors=expect_errors,
|
expect_errors=expect_errors,
|
||||||
headers=headers, extra_environ=extra_environ,
|
headers=headers, extra_environ=extra_environ,
|
||||||
|
@ -146,6 +149,9 @@ class FunctionalTest(base.DbTestCase):
|
||||||
with the request
|
with the request
|
||||||
:param status: expected status code of response
|
:param status: expected status code of response
|
||||||
"""
|
"""
|
||||||
|
# Provide member role for post request
|
||||||
|
if not headers:
|
||||||
|
headers = {"X-Roles": "member"}
|
||||||
return self._request_json(path=path, params=params,
|
return self._request_json(path=path, params=params,
|
||||||
expect_errors=expect_errors,
|
expect_errors=expect_errors,
|
||||||
headers=headers, extra_environ=extra_environ,
|
headers=headers, extra_environ=extra_environ,
|
||||||
|
@ -164,6 +170,9 @@ class FunctionalTest(base.DbTestCase):
|
||||||
with the request
|
with the request
|
||||||
:param status: expected status code of response
|
:param status: expected status code of response
|
||||||
"""
|
"""
|
||||||
|
# Provide member role for patch request
|
||||||
|
if not headers:
|
||||||
|
headers = {"X-Roles": "member"}
|
||||||
return self._request_json(path=path, params=params,
|
return self._request_json(path=path, params=params,
|
||||||
expect_errors=expect_errors,
|
expect_errors=expect_errors,
|
||||||
headers=headers, extra_environ=extra_environ,
|
headers=headers, extra_environ=extra_environ,
|
||||||
|
@ -184,6 +193,9 @@ class FunctionalTest(base.DbTestCase):
|
||||||
"""
|
"""
|
||||||
full_path = path_prefix + path
|
full_path = path_prefix + path
|
||||||
print('DELETE: %s' % (full_path))
|
print('DELETE: %s' % (full_path))
|
||||||
|
# Provide member role for delete request
|
||||||
|
if not headers:
|
||||||
|
headers = {"X-Roles": "member"}
|
||||||
response = self.app.delete(str(full_path),
|
response = self.app.delete(str(full_path),
|
||||||
headers=headers,
|
headers=headers,
|
||||||
status=status,
|
status=status,
|
||||||
|
@ -215,6 +227,10 @@ class FunctionalTest(base.DbTestCase):
|
||||||
'q.value': [],
|
'q.value': [],
|
||||||
'q.op': [],
|
'q.op': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Provide reader role for get request
|
||||||
|
if not headers:
|
||||||
|
headers = {"X-Roles": "reader"}
|
||||||
for query in q:
|
for query in q:
|
||||||
for name in ['field', 'op', 'value']:
|
for name in ['field', 'op', 'value']:
|
||||||
query_params['q.%s' % name].append(query.get(name, ''))
|
query_params['q.%s' % name].append(query.get(name, ''))
|
||||||
|
|
|
@ -132,7 +132,9 @@ class TestRootController(api_base.FunctionalTest):
|
||||||
response = app.get('/v1/')
|
response = app.get('/v1/')
|
||||||
self.assertEqual(self.v1_expected, response.json)
|
self.assertEqual(self.v1_expected, response.json)
|
||||||
|
|
||||||
response = app.get('/v1/clustertemplates')
|
response = app.get('/v1/clustertemplates',
|
||||||
|
headers={"X-Roles": "reader"}
|
||||||
|
)
|
||||||
self.assertEqual(200, response.status_int)
|
self.assertEqual(200, response.status_int)
|
||||||
|
|
||||||
def test_auth_with_no_public_routes(self):
|
def test_auth_with_no_public_routes(self):
|
||||||
|
|
|
@ -21,7 +21,14 @@ from magnum.tests.unit.api import utils as api_utils
|
||||||
from magnum.tests.unit.objects import utils as obj_utils
|
from magnum.tests.unit.objects import utils as obj_utils
|
||||||
|
|
||||||
|
|
||||||
HEADERS = {'OpenStack-API-Version': 'container-infra latest'}
|
READER_HEADERS = {
|
||||||
|
'OpenStack-API-Version': 'container-infra latest',
|
||||||
|
"X-Roles": "reader"
|
||||||
|
}
|
||||||
|
HEADERS = {
|
||||||
|
'OpenStack-API-Version': 'container-infra latest',
|
||||||
|
"X-Roles": "member"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestCertObject(base.TestCase):
|
class TestCertObject(base.TestCase):
|
||||||
|
@ -59,7 +66,7 @@ class TestGetCaCertificate(api_base.FunctionalTest):
|
||||||
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
||||||
|
|
||||||
response = self.get_json('/certificates/%s' % self.cluster.uuid,
|
response = self.get_json('/certificates/%s' % self.cluster.uuid,
|
||||||
headers=HEADERS)
|
headers=READER_HEADERS)
|
||||||
|
|
||||||
self.assertEqual(self.cluster.uuid, response['cluster_uuid'])
|
self.assertEqual(self.cluster.uuid, response['cluster_uuid'])
|
||||||
self.assertEqual(fake_cert['csr'], response['csr'])
|
self.assertEqual(fake_cert['csr'], response['csr'])
|
||||||
|
@ -72,7 +79,7 @@ class TestGetCaCertificate(api_base.FunctionalTest):
|
||||||
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
||||||
|
|
||||||
response = self.get_json('/certificates/%s' % self.cluster.name,
|
response = self.get_json('/certificates/%s' % self.cluster.name,
|
||||||
headers=HEADERS)
|
headers=READER_HEADERS)
|
||||||
|
|
||||||
self.assertEqual(self.cluster.uuid, response['cluster_uuid'])
|
self.assertEqual(self.cluster.uuid, response['cluster_uuid'])
|
||||||
self.assertEqual(fake_cert['csr'], response['csr'])
|
self.assertEqual(fake_cert['csr'], response['csr'])
|
||||||
|
@ -80,7 +87,8 @@ class TestGetCaCertificate(api_base.FunctionalTest):
|
||||||
|
|
||||||
def test_get_one_by_name_not_found(self):
|
def test_get_one_by_name_not_found(self):
|
||||||
response = self.get_json('/certificates/not_found',
|
response = self.get_json('/certificates/not_found',
|
||||||
expect_errors=True, headers=HEADERS)
|
expect_errors=True,
|
||||||
|
headers=READER_HEADERS)
|
||||||
|
|
||||||
self.assertEqual(404, response.status_int)
|
self.assertEqual(404, response.status_int)
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
|
@ -93,7 +101,8 @@ class TestGetCaCertificate(api_base.FunctionalTest):
|
||||||
uuid=uuidutils.generate_uuid())
|
uuid=uuidutils.generate_uuid())
|
||||||
|
|
||||||
response = self.get_json('/certificates/test_cluster',
|
response = self.get_json('/certificates/test_cluster',
|
||||||
expect_errors=True, headers=HEADERS)
|
expect_errors=True,
|
||||||
|
headers=READER_HEADERS)
|
||||||
|
|
||||||
self.assertEqual(409, response.status_int)
|
self.assertEqual(409, response.status_int)
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
|
@ -106,7 +115,7 @@ class TestGetCaCertificate(api_base.FunctionalTest):
|
||||||
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
||||||
|
|
||||||
response = self.get_json('/certificates/%s' % self.cluster.uuid,
|
response = self.get_json('/certificates/%s' % self.cluster.uuid,
|
||||||
headers=HEADERS)
|
headers=READER_HEADERS)
|
||||||
|
|
||||||
self.assertIn('links', response.keys())
|
self.assertIn('links', response.keys())
|
||||||
self.assertEqual(2, len(response['links']))
|
self.assertEqual(2, len(response['links']))
|
||||||
|
@ -244,7 +253,7 @@ class TestCertPolicyEnforcement(api_base.FunctionalTest):
|
||||||
self._common_policy_check(
|
self._common_policy_check(
|
||||||
"certificate:get", self.get_json,
|
"certificate:get", self.get_json,
|
||||||
'/certificates/%s' % cluster.uuid,
|
'/certificates/%s' % cluster.uuid,
|
||||||
expect_errors=True, headers=HEADERS)
|
expect_errors=True, headers=READER_HEADERS)
|
||||||
|
|
||||||
def test_policy_disallow_create(self):
|
def test_policy_disallow_create(self):
|
||||||
cluster = obj_utils.create_test_cluster(self.context)
|
cluster = obj_utils.create_test_cluster(self.context)
|
||||||
|
|
|
@ -494,7 +494,9 @@ class TestPatch(api_base.FunctionalTest):
|
||||||
'/clusters/%s/?rollback=True' % self.cluster_obj.uuid,
|
'/clusters/%s/?rollback=True' % self.cluster_obj.uuid,
|
||||||
[{'path': '/node_count', 'value': node_count,
|
[{'path': '/node_count', 'value': node_count,
|
||||||
'op': 'replace'}],
|
'op': 'replace'}],
|
||||||
headers={'OpenStack-API-Version': 'container-infra 1.3'})
|
headers={'OpenStack-API-Version': 'container-infra 1.3',
|
||||||
|
"X-Roles": "member"
|
||||||
|
})
|
||||||
|
|
||||||
self.mock_cluster_update.assert_called_once_with(
|
self.mock_cluster_update.assert_called_once_with(
|
||||||
mock.ANY, node_count, self.cluster_obj.health_status,
|
mock.ANY, node_count, self.cluster_obj.health_status,
|
||||||
|
@ -507,7 +509,9 @@ class TestPatch(api_base.FunctionalTest):
|
||||||
'/clusters/%s/?rollback=False' % self.cluster_obj.uuid,
|
'/clusters/%s/?rollback=False' % self.cluster_obj.uuid,
|
||||||
[{'path': '/node_count', 'value': node_count,
|
[{'path': '/node_count', 'value': node_count,
|
||||||
'op': 'replace'}],
|
'op': 'replace'}],
|
||||||
headers={'OpenStack-API-Version': 'container-infra 1.3'})
|
headers={'OpenStack-API-Version': 'container-infra 1.3',
|
||||||
|
"X-Roles": "member"
|
||||||
|
})
|
||||||
|
|
||||||
self.mock_cluster_update.assert_called_once_with(
|
self.mock_cluster_update.assert_called_once_with(
|
||||||
mock.ANY, node_count, self.cluster_obj.health_status,
|
mock.ANY, node_count, self.cluster_obj.health_status,
|
||||||
|
@ -520,7 +524,9 @@ class TestPatch(api_base.FunctionalTest):
|
||||||
'/clusters/%s' % self.cluster_obj.uuid,
|
'/clusters/%s' % self.cluster_obj.uuid,
|
||||||
[{'path': '/node_count', 'value': node_count,
|
[{'path': '/node_count', 'value': node_count,
|
||||||
'op': 'replace'}],
|
'op': 'replace'}],
|
||||||
headers={'OpenStack-API-Version': 'container-infra 1.9'},
|
headers={'OpenStack-API-Version': 'container-infra 1.9',
|
||||||
|
"X-Roles": "member"
|
||||||
|
},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
|
|
||||||
self.assertEqual(400, response.status_code)
|
self.assertEqual(400, response.status_code)
|
||||||
|
@ -531,7 +537,9 @@ class TestPatch(api_base.FunctionalTest):
|
||||||
'/clusters/%s' % self.cluster_obj.uuid,
|
'/clusters/%s' % self.cluster_obj.uuid,
|
||||||
[{'path': '/node_count', 'value': node_count,
|
[{'path': '/node_count', 'value': node_count,
|
||||||
'op': 'replace'}],
|
'op': 'replace'}],
|
||||||
headers={'OpenStack-API-Version': 'container-infra 1.10'})
|
headers={'OpenStack-API-Version': 'container-infra 1.10',
|
||||||
|
"X-Roles": "member"
|
||||||
|
})
|
||||||
|
|
||||||
self.mock_cluster_update.assert_called_once_with(
|
self.mock_cluster_update.assert_called_once_with(
|
||||||
mock.ANY, node_count, self.cluster_obj.health_status,
|
mock.ANY, node_count, self.cluster_obj.health_status,
|
||||||
|
@ -708,18 +716,24 @@ class TestPost(api_base.FunctionalTest):
|
||||||
def test_create_cluster_with_zero_node_count_fail(self):
|
def test_create_cluster_with_zero_node_count_fail(self):
|
||||||
bdict = apiutils.cluster_post_data()
|
bdict = apiutils.cluster_post_data()
|
||||||
bdict['node_count'] = 0
|
bdict['node_count'] = 0
|
||||||
response = self.post_json('/clusters', bdict, expect_errors=True,
|
response = self.post_json(
|
||||||
headers={"Openstack-Api-Version":
|
'/clusters', bdict, expect_errors=True,
|
||||||
"container-infra 1.9"})
|
headers={
|
||||||
|
"Openstack-Api-Version": "container-infra 1.9",
|
||||||
|
"X-Roles": "member"
|
||||||
|
})
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
self.assertEqual(400, response.status_int)
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
def test_create_cluster_with_zero_node_count(self):
|
def test_create_cluster_with_zero_node_count(self):
|
||||||
bdict = apiutils.cluster_post_data()
|
bdict = apiutils.cluster_post_data()
|
||||||
bdict['node_count'] = 0
|
bdict['node_count'] = 0
|
||||||
response = self.post_json('/clusters', bdict,
|
response = self.post_json(
|
||||||
headers={"Openstack-Api-Version":
|
'/clusters', bdict,
|
||||||
"container-infra 1.10"})
|
headers={
|
||||||
|
"Openstack-Api-Version": "container-infra 1.10",
|
||||||
|
"X-Roles": "member"
|
||||||
|
})
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
self.assertEqual(202, response.status_int)
|
self.assertEqual(202, response.status_int)
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
{"node_count": new_node_count},
|
{"node_count": new_node_count},
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.7"})
|
"container-infra 1.7",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
|
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
|
||||||
|
@ -69,7 +70,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_resize_req,
|
cluster_resize_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"})
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
|
response = self.get_json('/clusters/%s' % self.cluster_obj.uuid)
|
||||||
|
@ -89,7 +91,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_resize_req,
|
cluster_resize_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"},
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(400, response.status_code)
|
self.assertEqual(400, response.status_code)
|
||||||
|
|
||||||
|
@ -106,7 +109,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_resize_req,
|
cluster_resize_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"},
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(400, response.status_code)
|
self.assertEqual(400, response.status_code)
|
||||||
|
|
||||||
|
@ -123,7 +127,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_resize_req,
|
cluster_resize_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"},
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(400, response.status_code)
|
self.assertEqual(400, response.status_code)
|
||||||
|
|
||||||
|
@ -140,7 +145,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_resize_req,
|
cluster_resize_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"},
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(400, response.status_code)
|
self.assertEqual(400, response.status_code)
|
||||||
|
|
||||||
|
@ -157,7 +163,8 @@ class TestClusterResize(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_resize_req,
|
cluster_resize_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.10"})
|
"container-infra 1.10",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,7 +202,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.8"})
|
"container-infra 1.8",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
def test_upgrade_cluster_as_admin(self):
|
def test_upgrade_cluster_as_admin(self):
|
||||||
|
@ -226,7 +234,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
'/clusters/%s/actions/upgrade' %
|
'/clusters/%s/actions/upgrade' %
|
||||||
cluster_uuid,
|
cluster_uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version": "container-infra 1.8"})
|
headers={"Openstack-Api-Version": "container-infra 1.8",
|
||||||
|
"X-Roles": "member"})
|
||||||
|
|
||||||
self.assertEqual(202, response.status_int)
|
self.assertEqual(202, response.status_int)
|
||||||
|
|
||||||
|
@ -239,7 +248,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"})
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
def test_upgrade_default_master(self):
|
def test_upgrade_default_master(self):
|
||||||
|
@ -251,7 +261,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"})
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
def test_upgrade_non_default_ng(self):
|
def test_upgrade_non_default_ng(self):
|
||||||
|
@ -263,7 +274,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"})
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"})
|
||||||
self.assertEqual(202, response.status_code)
|
self.assertEqual(202, response.status_code)
|
||||||
|
|
||||||
def test_upgrade_cluster_not_found(self):
|
def test_upgrade_cluster_not_found(self):
|
||||||
|
@ -273,7 +285,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
response = self.post_json('/clusters/not_there/actions/upgrade',
|
response = self.post_json('/clusters/not_there/actions/upgrade',
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.8"},
|
"container-infra 1.8",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(404, response.status_code)
|
self.assertEqual(404, response.status_code)
|
||||||
|
|
||||||
|
@ -285,7 +298,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.8"},
|
"container-infra 1.8",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(404, response.status_code)
|
self.assertEqual(404, response.status_code)
|
||||||
|
|
||||||
|
@ -298,7 +312,8 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"},
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(404, response.status_code)
|
self.assertEqual(404, response.status_code)
|
||||||
|
|
||||||
|
@ -311,6 +326,7 @@ class TestClusterUpgrade(api_base.FunctionalTest):
|
||||||
self.cluster_obj.uuid,
|
self.cluster_obj.uuid,
|
||||||
cluster_upgrade_req,
|
cluster_upgrade_req,
|
||||||
headers={"Openstack-Api-Version":
|
headers={"Openstack-Api-Version":
|
||||||
"container-infra 1.9"},
|
"container-infra 1.9",
|
||||||
|
"X-Roles": "member"},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
self.assertEqual(409, response.status_code)
|
self.assertEqual(409, response.status_code)
|
||||||
|
|
|
@ -47,24 +47,26 @@ class TestNodegroupObject(base.TestCase):
|
||||||
class NodeGroupControllerTest(api_base.FunctionalTest):
|
class NodeGroupControllerTest(api_base.FunctionalTest):
|
||||||
headers = {"Openstack-Api-Version": "container-infra latest"}
|
headers = {"Openstack-Api-Version": "container-infra latest"}
|
||||||
|
|
||||||
def _add_headers(self, kwargs):
|
def _add_headers(self, kwargs, roles=None):
|
||||||
if 'headers' not in kwargs:
|
if 'headers' not in kwargs:
|
||||||
kwargs['headers'] = self.headers
|
kwargs['headers'] = self.headers
|
||||||
|
if roles:
|
||||||
|
kwargs['headers']['X-Roles'] = ",".join(roles)
|
||||||
|
|
||||||
def get_json(self, *args, **kwargs):
|
def get_json(self, *args, **kwargs):
|
||||||
self._add_headers(kwargs)
|
self._add_headers(kwargs, roles=['reader'])
|
||||||
return super(NodeGroupControllerTest, self).get_json(*args, **kwargs)
|
return super(NodeGroupControllerTest, self).get_json(*args, **kwargs)
|
||||||
|
|
||||||
def post_json(self, *args, **kwargs):
|
def post_json(self, *args, **kwargs):
|
||||||
self._add_headers(kwargs)
|
self._add_headers(kwargs, roles=['member'])
|
||||||
return super(NodeGroupControllerTest, self).post_json(*args, **kwargs)
|
return super(NodeGroupControllerTest, self).post_json(*args, **kwargs)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
self._add_headers(kwargs)
|
self._add_headers(kwargs, roles=['member'])
|
||||||
return super(NodeGroupControllerTest, self).delete(*args, **kwargs)
|
return super(NodeGroupControllerTest, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
def patch_json(self, *args, **kwargs):
|
def patch_json(self, *args, **kwargs):
|
||||||
self._add_headers(kwargs)
|
self._add_headers(kwargs, roles=['member'])
|
||||||
return super(NodeGroupControllerTest, self).patch_json(*args, **kwargs)
|
return super(NodeGroupControllerTest, self).patch_json(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ class TestQuota(api_base.FunctionalTest):
|
||||||
project_id="proj-id-"+str(i))
|
project_id="proj-id-"+str(i))
|
||||||
quota_list.append(quota)
|
quota_list.append(quota)
|
||||||
|
|
||||||
headers = {'X-Project-Id': 'proj-id-2'}
|
headers = {'X-Project-Id': 'proj-id-2', "X-Roles": "member"}
|
||||||
response = self.get_json('/quotas', headers=headers)
|
response = self.get_json('/quotas', headers=headers)
|
||||||
self.assertEqual(1, len(response['quotas']))
|
self.assertEqual(1, len(response['quotas']))
|
||||||
self.assertEqual('proj-id-2', response['quotas'][0]['project_id'])
|
self.assertEqual('proj-id-2', response['quotas'][0]['project_id'])
|
||||||
|
|
|
@ -21,7 +21,14 @@ from magnum.tests.unit.objects import utils as obj_utils
|
||||||
class TestStatsController(api_base.FunctionalTest):
|
class TestStatsController(api_base.FunctionalTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.base_headers = {'OpenStack-API-Version': 'container-infra 1.4'}
|
self.base_headers = {
|
||||||
|
"X-Roles": "reader",
|
||||||
|
"OpenStack-API-Version": "container-infra 1.4"
|
||||||
|
}
|
||||||
|
self.base_admin_headers = {
|
||||||
|
"X-Roles": "admin",
|
||||||
|
"OpenStack-API-Version": "container-infra 1.4"
|
||||||
|
}
|
||||||
super(TestStatsController, self).setUp()
|
super(TestStatsController, self).setUp()
|
||||||
obj_utils.create_test_cluster_template(self.context)
|
obj_utils.create_test_cluster_template(self.context)
|
||||||
|
|
||||||
|
@ -39,7 +46,7 @@ class TestStatsController(api_base.FunctionalTest):
|
||||||
obj_utils.create_test_cluster(self.context,
|
obj_utils.create_test_cluster(self.context,
|
||||||
project_id=234,
|
project_id=234,
|
||||||
uuid='uuid2')
|
uuid='uuid2')
|
||||||
response = self.get_json('/stats', headers=self.base_headers)
|
response = self.get_json('/stats', headers=self.base_admin_headers)
|
||||||
expected = {u'clusters': 2, u'nodes': 12}
|
expected = {u'clusters': 2, u'nodes': 12}
|
||||||
self.assertEqual(expected, response)
|
self.assertEqual(expected, response)
|
||||||
|
|
||||||
|
@ -54,7 +61,7 @@ class TestStatsController(api_base.FunctionalTest):
|
||||||
uuid='uuid2')
|
uuid='uuid2')
|
||||||
self.context.is_admin = True
|
self.context.is_admin = True
|
||||||
response = self.get_json('/stats?project_id=234',
|
response = self.get_json('/stats?project_id=234',
|
||||||
headers=self.base_headers)
|
headers=self.base_admin_headers)
|
||||||
expected = {u'clusters': 1, u'nodes': 6}
|
expected = {u'clusters': 1, u'nodes': 6}
|
||||||
self.assertEqual(expected, response)
|
self.assertEqual(expected, response)
|
||||||
|
|
||||||
|
@ -69,7 +76,7 @@ class TestStatsController(api_base.FunctionalTest):
|
||||||
uuid='uuid2')
|
uuid='uuid2')
|
||||||
self.context.is_admin = True
|
self.context.is_admin = True
|
||||||
response = self.get_json('/stats?project_id=34',
|
response = self.get_json('/stats?project_id=34',
|
||||||
headers=self.base_headers)
|
headers=self.base_admin_headers)
|
||||||
expected = {u'clusters': 0, u'nodes': 0}
|
expected = {u'clusters': 0, u'nodes': 0}
|
||||||
self.assertEqual(expected, response)
|
self.assertEqual(expected, response)
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ class TestContextHook(base.BaseTestCase):
|
||||||
super(TestContextHook, self).setUp()
|
super(TestContextHook, self).setUp()
|
||||||
self.app = fakes.FakeApp()
|
self.app = fakes.FakeApp()
|
||||||
|
|
||||||
def test_context_hook_before_method(self):
|
@mock.patch("magnum.common.policy.check_is_admin")
|
||||||
|
def test_context_hook_before_method(self, m_c):
|
||||||
state = mock.Mock(request=fakes.FakePecanRequest())
|
state = mock.Mock(request=fakes.FakePecanRequest())
|
||||||
hook = hooks.ContextHook()
|
hook = hooks.ContextHook()
|
||||||
hook.before(state)
|
hook.before(state)
|
||||||
|
@ -51,12 +52,13 @@ class TestContextHook(base.BaseTestCase):
|
||||||
self.assertEqual(fakes.fakeAuthTokenHeaders['X-Roles'],
|
self.assertEqual(fakes.fakeAuthTokenHeaders['X-Roles'],
|
||||||
','.join(ctx.roles))
|
','.join(ctx.roles))
|
||||||
self.assertEqual(fakes.fakeAuthTokenHeaders['X-User-Domain-Name'],
|
self.assertEqual(fakes.fakeAuthTokenHeaders['X-User-Domain-Name'],
|
||||||
ctx.domain_name)
|
ctx.user_domain_name)
|
||||||
self.assertEqual(fakes.fakeAuthTokenHeaders['X-User-Domain-Id'],
|
self.assertEqual(fakes.fakeAuthTokenHeaders['X-User-Domain-Id'],
|
||||||
ctx.domain_id)
|
ctx.user_domain_id)
|
||||||
self.assertIsNone(ctx.auth_token_info)
|
self.assertIsNone(ctx.auth_token_info)
|
||||||
|
|
||||||
def test_context_hook_before_method_auth_info(self):
|
@mock.patch("magnum.common.policy.check_is_admin")
|
||||||
|
def test_context_hook_before_method_auth_info(self, c_m):
|
||||||
state = mock.Mock(request=fakes.FakePecanRequest())
|
state = mock.Mock(request=fakes.FakePecanRequest())
|
||||||
state.request.environ['keystone.token_info'] = 'assert_this'
|
state.request.environ['keystone.token_info'] = 'assert_this'
|
||||||
hook = hooks.ContextHook()
|
hook = hooks.ContextHook()
|
||||||
|
|
|
@ -19,29 +19,30 @@ from magnum.tests import base
|
||||||
class ContextTestCase(base.TestCase):
|
class ContextTestCase(base.TestCase):
|
||||||
|
|
||||||
def _create_context(self, roles=None):
|
def _create_context(self, roles=None):
|
||||||
return magnum_context.RequestContext(auth_token='auth_token1',
|
return magnum_context.RequestContext(
|
||||||
auth_url='auth_url1',
|
auth_token='auth_token1',
|
||||||
domain_id='domain_id1',
|
auth_url='auth_url1',
|
||||||
domain_name='domain_name1',
|
user_domain_id='user_domain_id1',
|
||||||
user_name='user1',
|
user_domain_name='user_domain_name1',
|
||||||
user_id='user-id1',
|
user_name='user1',
|
||||||
project_name='tenant1',
|
user_id='user-id1',
|
||||||
project_id='tenant-id1',
|
project_name='tenant1',
|
||||||
roles=roles,
|
project_id='tenant-id1',
|
||||||
is_admin=True,
|
roles=roles,
|
||||||
read_only=True,
|
is_admin=True,
|
||||||
show_deleted=True,
|
read_only=True,
|
||||||
request_id='request_id1',
|
show_deleted=True,
|
||||||
trust_id='trust_id1',
|
request_id='request_id1',
|
||||||
auth_token_info='token_info1')
|
trust_id='trust_id1',
|
||||||
|
auth_token_info='token_info1')
|
||||||
|
|
||||||
def test_context(self):
|
def test_context(self):
|
||||||
ctx = self._create_context()
|
ctx = self._create_context()
|
||||||
|
|
||||||
self.assertEqual("auth_token1", ctx.auth_token)
|
self.assertEqual("auth_token1", ctx.auth_token)
|
||||||
self.assertEqual("auth_url1", ctx.auth_url)
|
self.assertEqual("auth_url1", ctx.auth_url)
|
||||||
self.assertEqual("domain_id1", ctx.domain_id)
|
self.assertEqual("user_domain_id1", ctx.user_domain_id)
|
||||||
self.assertEqual("domain_name1", ctx.domain_name)
|
self.assertEqual("user_domain_name1", ctx.user_domain_name)
|
||||||
self.assertEqual("user1", ctx.user_name)
|
self.assertEqual("user1", ctx.user_name)
|
||||||
self.assertEqual("user-id1", ctx.user_id)
|
self.assertEqual("user-id1", ctx.user_id)
|
||||||
self.assertEqual("tenant1", ctx.project_name)
|
self.assertEqual("tenant1", ctx.project_name)
|
||||||
|
@ -59,8 +60,8 @@ class ContextTestCase(base.TestCase):
|
||||||
|
|
||||||
self.assertEqual("auth_token1", ctx.auth_token)
|
self.assertEqual("auth_token1", ctx.auth_token)
|
||||||
self.assertEqual("auth_url1", ctx.auth_url)
|
self.assertEqual("auth_url1", ctx.auth_url)
|
||||||
self.assertEqual("domain_id1", ctx.domain_id)
|
self.assertEqual("user_domain_id1", ctx.user_domain_id)
|
||||||
self.assertEqual("domain_name1", ctx.domain_name)
|
self.assertEqual("user_domain_name1", ctx.user_domain_name)
|
||||||
self.assertEqual("user1", ctx.user_name)
|
self.assertEqual("user1", ctx.user_name)
|
||||||
self.assertEqual("user-id1", ctx.user_id)
|
self.assertEqual("user-id1", ctx.user_id)
|
||||||
self.assertEqual("tenant1", ctx.project_name)
|
self.assertEqual("tenant1", ctx.project_name)
|
||||||
|
@ -80,8 +81,8 @@ class ContextTestCase(base.TestCase):
|
||||||
|
|
||||||
self.assertEqual(ctx.auth_token, ctx2.auth_token)
|
self.assertEqual(ctx.auth_token, ctx2.auth_token)
|
||||||
self.assertEqual(ctx.auth_url, ctx2.auth_url)
|
self.assertEqual(ctx.auth_url, ctx2.auth_url)
|
||||||
self.assertEqual(ctx.domain_id, ctx2.domain_id)
|
self.assertEqual(ctx.user_domain_id, ctx2.user_domain_id)
|
||||||
self.assertEqual(ctx.domain_name, ctx2.domain_name)
|
self.assertEqual(ctx.user_domain_name, ctx2.user_domain_name)
|
||||||
self.assertEqual(ctx.user_name, ctx2.user_name)
|
self.assertEqual(ctx.user_name, ctx2.user_name)
|
||||||
self.assertEqual(ctx.user_id, ctx2.user_id)
|
self.assertEqual(ctx.user_id, ctx2.user_id)
|
||||||
self.assertEqual(ctx.project_id, ctx2.project_id)
|
self.assertEqual(ctx.project_id, ctx2.project_id)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
The Magnum service now allows enables policies (RBAC) new defaults
|
||||||
|
and scope checks. These are controlled by the following (default) config
|
||||||
|
options in ``magnum.conf`` file::
|
||||||
|
|
||||||
|
[oslo_policy]
|
||||||
|
enforce_new_defaults=False
|
||||||
|
enforce_scope=False
|
||||||
|
|
||||||
|
We will change the default to True in 2024.1 (Caracal) cycle.
|
||||||
|
If you want to enable them then modify both values to True.
|
|
@ -28,10 +28,10 @@ oslo.config>=8.1.0 # Apache-2.0
|
||||||
oslo.context>=3.1.0 # Apache-2.0
|
oslo.context>=3.1.0 # Apache-2.0
|
||||||
oslo.db>=8.2.0 # Apache-2.0
|
oslo.db>=8.2.0 # Apache-2.0
|
||||||
oslo.i18n>=5.0.0 # Apache-2.0
|
oslo.i18n>=5.0.0 # Apache-2.0
|
||||||
oslo.log>=4.2.0 # Apache-2.0
|
oslo.log>=4.8.0 # Apache-2.0
|
||||||
oslo.messaging>=14.1.0 # Apache-2.0
|
oslo.messaging>=14.1.0 # Apache-2.0
|
||||||
oslo.middleware>=4.1.0 # Apache-2.0
|
oslo.middleware>=4.1.0 # Apache-2.0
|
||||||
oslo.policy>=3.6.0 # Apache-2.0
|
oslo.policy>=3.11.0 # Apache-2.0
|
||||||
oslo.reports>=2.1.0 # Apache-2.0
|
oslo.reports>=2.1.0 # Apache-2.0
|
||||||
oslo.serialization>=3.2.0 # Apache-2.0
|
oslo.serialization>=3.2.0 # Apache-2.0
|
||||||
oslo.service>=2.2.0 # Apache-2.0
|
oslo.service>=2.2.0 # Apache-2.0
|
||||||
|
|
Loading…
Reference in New Issue