Support Reader Role for sw-manager

This commit adds support for reader role for all sw-manager
commands. The behavior is that "get" commands like
"upgrade-strategy show" requires reader role in the admin or services
project. Other commands requires admin role in the admin or services
project. Before this change, all the commands affected by the change
checks the admin_in_system_projects rule. Now they either check
rules with different names but same effect for customizability,
or check for reader role. The overall effect is loosening the
restrictions on "get" style commands.

Test Cases:

PASS: Existing admin user can execute all commands
PASS: New admin user with admin role in admin project behaves like
      existing admin
PASS: New user with reader role can only run sw-manager something show.
      apply, abort, create and delete denies the request
PASS: New admin user of a different project but has no roles, admin
      or reader in the admin project is denied all access
PASS: dcmanager user behaves like existing admin.
PASS: horizon GUI access

Change-Id: I0d924b91583efb8191202f142f12d8f151f6feec
Story: 2010149
Task: 46119
Signed-off-by: Jerry Sun <jerry.sun@windriver.com>
This commit is contained in:
Jerry Sun 2022-08-25 09:21:09 -04:00
parent 7b9254b55a
commit 0f3aeaa839
8 changed files with 309 additions and 46 deletions

View File

@ -7,7 +7,13 @@
import itertools
from nfv_vim.api.acl.policies import base
from nfv_vim.api.acl.policies import fw_update_strategy_policy
from nfv_vim.api.acl.policies import kube_rootca_update_strategy_policy
from nfv_vim.api.acl.policies import kube_upgrade_strategy_policy
from nfv_vim.api.acl.policies import sw_patch_strategy_policy
from nfv_vim.api.acl.policies import sw_update_strategy_policy
from nfv_vim.api.acl.policies import sw_upgrade_strategy_policy
from nfv_vim.api.acl import policy
from nfv_vim.api import openstack
@ -35,7 +41,12 @@ class AuthenticationApplication(object):
nfv_vim_rules = itertools.chain(
base.list_rules(),
sw_update_strategy_policy.list_rules()
sw_update_strategy_policy.list_rules(),
fw_update_strategy_policy.list_rules(),
kube_rootca_update_strategy_policy.list_rules(),
kube_upgrade_strategy_policy.list_rules(),
sw_patch_strategy_policy.list_rules(),
sw_upgrade_strategy_policy.list_rules()
)
rules = policy.Rules.load_rules(policy_file_contents,
default_rule,

View File

@ -0,0 +1,42 @@
# Copyright (c) 2022 Wind River Systems, Inc.
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
from nfv_vim.api.acl.policies import base
POLICY_ROOT = 'nfv_api:fw_update_strategy:%s'
fw_update_strategy_rules = [
base.RuleDefault(
name=POLICY_ROOT % 'add',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a fw_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'delete',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a fw_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'get',
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get a fw_update_strategy",
)
]
def list_rules():
return fw_update_strategy_rules

View File

@ -0,0 +1,42 @@
# Copyright (c) 2022 Wind River Systems, Inc.
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
from nfv_vim.api.acl.policies import base
POLICY_ROOT = 'nfv_api:kube_rootca_update_strategy:%s'
kube_rootca_update_strategy_rules = [
base.RuleDefault(
name=POLICY_ROOT % 'add',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a kube_rootca_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'delete',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a kube_rootca_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'get',
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get a kube_rootca_update_strategy",
)
]
def list_rules():
return kube_rootca_update_strategy_rules

View File

@ -0,0 +1,42 @@
# Copyright (c) 2022 Wind River Systems, Inc.
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
from nfv_vim.api.acl.policies import base
POLICY_ROOT = 'nfv_api:kube_upgrade_strategy:%s'
kube_upgrade_strategy_rules = [
base.RuleDefault(
name=POLICY_ROOT % 'add',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a kube_upgrade_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'delete',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a kube_upgrade_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'get',
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get a kube_upgrade_strategy",
)
]
def list_rules():
return kube_upgrade_strategy_rules

View File

@ -0,0 +1,42 @@
# Copyright (c) 2022 Wind River Systems, Inc.
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
from nfv_vim.api.acl.policies import base
POLICY_ROOT = 'nfv_api:sw_patch_strategy:%s'
sw_patch_strategy_rules = [
base.RuleDefault(
name=POLICY_ROOT % 'add',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a sw_patch_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'delete',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a sw_patch_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'get',
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get a sw_patch_strategy",
)
]
def list_rules():
return sw_patch_strategy_rules

View File

@ -13,6 +13,23 @@
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
# "SwUpdateStrategyActionAPI" need to handle the post "controller api method"
# common to all 5 apply and aborts "sw-manager commands"
#
# FwUpdateStrategyAPI
# KubeRootcaUpdateStrategyAPI
# KubeUpgradeStrategyAPI
# SwPatchStrategyAPI
# SwUpgradeStrategyAPI
#
# those 5 classes needs to handle get_all, post, delete "controller api methods"
# for show, create, delete "sw-manager commands" respectively
#
# There are 5 sw-manager commands and 6 controller api classes.
# We need 6 policy classes because the 5 controller api classes handle 3/5
# of their commands and inherit from this 6th class to handle the other 2.
# This policy class is for "SwUpdateStrategyActionAPI"
from nfv_vim.api.acl.policies import base
@ -20,30 +37,12 @@ POLICY_ROOT = 'nfv_api:sw_update_strategy:%s'
sw_update_strategy_rules = [
# this rule handles the 'apply' and 'abort' commands, both of which
# comes into the controller as 'post' requests.
base.RuleDefault(
name=POLICY_ROOT % 'add',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a sw_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'apply',
name=POLICY_ROOT % 'post',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Apply sw_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'delete',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a sw_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'get',
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get a sw_update_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'modify',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Modify Service Parameter value.",
)
]

View File

@ -0,0 +1,42 @@
# Copyright (c) 2022 Wind River Systems, Inc.
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
from nfv_vim.api.acl.policies import base
POLICY_ROOT = 'nfv_api:sw_upgrade_strategy:%s'
sw_upgrade_strategy_rules = [
base.RuleDefault(
name=POLICY_ROOT % 'add',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a sw_upgrade_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'delete',
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a sw_upgrade_strategy",
),
base.RuleDefault(
name=POLICY_ROOT % 'get',
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get a sw_upgrade_strategy",
)
]
def list_rules():
return sw_upgrade_strategy_rules

View File

@ -13,7 +13,12 @@ import wsmeext.pecan as wsme_pecan
from nfv_common import debug
from nfv_common import validate
from nfv_vim.api.acl.policies import fw_update_strategy_policy
from nfv_vim.api.acl.policies import kube_rootca_update_strategy_policy
from nfv_vim.api.acl.policies import kube_upgrade_strategy_policy
from nfv_vim.api.acl.policies import sw_patch_strategy_policy
from nfv_vim.api.acl.policies import sw_update_strategy_policy
from nfv_vim.api.acl.policies import sw_upgrade_strategy_policy
from nfv_vim.api.acl import policy
from nfv_vim import rpc
@ -437,21 +442,9 @@ class SwUpdateStrategyActionAPI(rest.RestController):
def enforce_policy(self, method_name, auth_context_dict):
"""Check policy rules for each action of this controller."""
if method_name == "apply":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "apply", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "delete":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "delete", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name in ["get_all", "get_one"]:
policy.check(sw_update_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "patch":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "modify", {},
auth_context_dict, exc=policy.PolicyForbidden)
# this handles the apply and abort requests
elif method_name == "post":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "apply", {},
if method_name == "post":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "post", {},
auth_context_dict, exc=policy.PolicyForbidden)
else:
policy.check('admin_in_system_projects', {}, auth_context_dict)
@ -621,20 +614,14 @@ class SwPatchStrategyAPI(SwUpdateStrategyAPI):
def enforce_policy(self, method_name, auth_context_dict):
"""Check policy rules for each action of this controller."""
if method_name == "apply":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "apply", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "delete":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "delete", {},
if method_name == "delete":
policy.check(sw_patch_strategy_policy.POLICY_ROOT % "delete", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name in ["get_all", "get_one"]:
policy.check(sw_update_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "patch":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "modify", {},
policy.check(sw_patch_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "post":
policy.check(sw_update_strategy_policy.POLICY_ROOT % "add", {},
policy.check(sw_patch_strategy_policy.POLICY_ROOT % "add", {},
auth_context_dict, exc=policy.PolicyForbidden)
else:
policy.check('admin_in_system_projects', {}, auth_context_dict)
@ -693,6 +680,20 @@ class SwUpgradeStrategyAPI(SwUpdateStrategyAPI):
DLOG.error("Unexpected result received, result=%s." % response.result)
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
def enforce_policy(self, method_name, auth_context_dict):
"""Check policy rules for each action of this controller."""
if method_name == "delete":
policy.check(sw_upgrade_strategy_policy.POLICY_ROOT % "delete", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name in ["get_all", "get_one"]:
policy.check(sw_upgrade_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "post":
policy.check(sw_upgrade_strategy_policy.POLICY_ROOT % "add", {},
auth_context_dict, exc=policy.PolicyForbidden)
else:
policy.check('admin_in_system_projects', {}, auth_context_dict)
class FwUpdateStrategyAPI(SwUpdateStrategyAPI):
"""
@ -743,6 +744,20 @@ class FwUpdateStrategyAPI(SwUpdateStrategyAPI):
DLOG.error("Unexpected result received, result=%s." % response.result)
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
def enforce_policy(self, method_name, auth_context_dict):
"""Check policy rules for each action of this controller."""
if method_name == "delete":
policy.check(fw_update_strategy_policy.POLICY_ROOT % "delete", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name in ["get_all", "get_one"]:
policy.check(fw_update_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "post":
policy.check(fw_update_strategy_policy.POLICY_ROOT % "add", {},
auth_context_dict, exc=policy.PolicyForbidden)
else:
policy.check('admin_in_system_projects', {}, auth_context_dict)
class KubeRootcaUpdateStrategyAPI(SwUpdateStrategyAPI):
"""
@ -819,6 +834,20 @@ class KubeRootcaUpdateStrategyAPI(SwUpdateStrategyAPI):
DLOG.error("Unexpected result received, result=%s." % response.result)
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
def enforce_policy(self, method_name, auth_context_dict):
"""Check policy rules for each action of this controller."""
if method_name == "delete":
policy.check(kube_rootca_update_strategy_policy.POLICY_ROOT % "delete", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name in ["get_all", "get_one"]:
policy.check(kube_rootca_update_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "post":
policy.check(kube_rootca_update_strategy_policy.POLICY_ROOT % "add", {},
auth_context_dict, exc=policy.PolicyForbidden)
else:
policy.check('admin_in_system_projects', {}, auth_context_dict)
class KubeUpgradeStrategyAPI(SwUpdateStrategyAPI):
"""
@ -877,3 +906,17 @@ class KubeUpgradeStrategyAPI(SwUpdateStrategyAPI):
DLOG.error("Unexpected result received, result=%s." % response.result)
return pecan.abort(httplib.INTERNAL_SERVER_ERROR)
def enforce_policy(self, method_name, auth_context_dict):
"""Check policy rules for each action of this controller."""
if method_name == "delete":
policy.check(kube_upgrade_strategy_policy.POLICY_ROOT % "delete", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name in ["get_all", "get_one"]:
policy.check(kube_upgrade_strategy_policy.POLICY_ROOT % "get", {},
auth_context_dict, exc=policy.PolicyForbidden)
elif method_name == "post":
policy.check(kube_upgrade_strategy_policy.POLICY_ROOT % "add", {},
auth_context_dict, exc=policy.PolicyForbidden)
else:
policy.check('admin_in_system_projects', {}, auth_context_dict)