Merge "Register default policies in code"

This commit is contained in:
Zuul 2017-12-12 03:38:13 +00:00 committed by Gerrit Code Review
commit aa2b213a45
16 changed files with 680 additions and 49 deletions

View File

@ -42,7 +42,7 @@ WATCHER_AUTH_CACHE_DIR=${WATCHER_AUTH_CACHE_DIR:-/var/cache/watcher}
WATCHER_CONF_DIR=/etc/watcher
WATCHER_CONF=$WATCHER_CONF_DIR/watcher.conf
WATCHER_POLICY_JSON=$WATCHER_CONF_DIR/policy.json
WATCHER_POLICY_YAML=$WATCHER_CONF_DIR/policy.yaml.sample
WATCHER_DEVSTACK_DIR=$WATCHER_DIR/devstack
WATCHER_DEVSTACK_FILES_DIR=$WATCHER_DEVSTACK_DIR/files
@ -106,7 +106,25 @@ function configure_watcher {
# Put config files in ``/etc/watcher`` for everyone to find
sudo install -d -o $STACK_USER $WATCHER_CONF_DIR
install_default_policy watcher
local project=watcher
local project_uc
project_uc=$(echo watcher|tr a-z A-Z)
local conf_dir="${project_uc}_CONF_DIR"
# eval conf dir to get the variable
conf_dir="${!conf_dir}"
local project_dir="${project_uc}_DIR"
# eval project dir to get the variable
project_dir="${!project_dir}"
local sample_conf_dir="${project_dir}/etc/${project}"
local sample_policy_dir="${project_dir}/etc/${project}/policy.d"
local sample_policy_generator="${project_dir}/etc/${project}/oslo-policy-generator/watcher-policy-generator.conf"
# first generate policy.yaml
oslopolicy-sample-generator --config-file $sample_policy_generator
# then optionally copy over policy.d
if [[ -d $sample_policy_dir ]]; then
cp -r $sample_policy_dir $conf_dir/policy.d
fi
# Rebuild the config file from scratch
create_watcher_conf
@ -163,7 +181,7 @@ function create_watcher_conf {
iniset $WATCHER_CONF api host "$WATCHER_SERVICE_HOST"
iniset $WATCHER_CONF api port "$WATCHER_SERVICE_PORT"
iniset $WATCHER_CONF oslo_policy policy_file $WATCHER_POLICY_JSON
iniset $WATCHER_CONF oslo_policy policy_file $WATCHER_POLICY_YAML
iniset $WATCHER_CONF oslo_messaging_rabbit rabbit_userid $RABBIT_USERID
iniset $WATCHER_CONF oslo_messaging_rabbit rabbit_password $RABBIT_PASSWORD

View File

@ -0,0 +1,3 @@
[DEFAULT]
output_file = /etc/watcher/policy.yaml.sample
namespace = watcher

View File

@ -1,45 +0,0 @@
{
"admin_api": "role:admin or role:administrator",
"show_password": "!",
"default": "rule:admin_api",
"action:detail": "rule:default",
"action:get": "rule:default",
"action:get_all": "rule:default",
"action_plan:delete": "rule:default",
"action_plan:detail": "rule:default",
"action_plan:get": "rule:default",
"action_plan:get_all": "rule:default",
"action_plan:update": "rule:default",
"audit:create": "rule:default",
"audit:delete": "rule:default",
"audit:detail": "rule:default",
"audit:get": "rule:default",
"audit:get_all": "rule:default",
"audit:update": "rule:default",
"audit_template:create": "rule:default",
"audit_template:delete": "rule:default",
"audit_template:detail": "rule:default",
"audit_template:get": "rule:default",
"audit_template:get_all": "rule:default",
"audit_template:update": "rule:default",
"goal:detail": "rule:default",
"goal:get": "rule:default",
"goal:get_all": "rule:default",
"scoring_engine:detail": "rule:default",
"scoring_engine:get": "rule:default",
"scoring_engine:get_all": "rule:default",
"strategy:detail": "rule:default",
"strategy:get": "rule:default",
"strategy:get_all": "rule:default",
"service:detail": "rule:default",
"service:get": "rule:default",
"service:get_all": "rule:default"
}

View File

@ -32,6 +32,12 @@ setup-hooks =
oslo.config.opts =
watcher = watcher.conf.opts:list_opts
oslo.policy.policies =
watcher = watcher.common.policies:list_rules
oslo.policy.enforcer =
watcher = watcher.common.policy:get_enforcer
console_scripts =
watcher-api = watcher.cmd.api:main
watcher-db-manage = watcher.cmd.dbmanage:main

View File

@ -46,6 +46,10 @@ sitepackages = False
commands =
oslo-config-generator --config-file etc/watcher/oslo-config-generator/watcher.conf
[testenv:genpolicy]
commands =
oslopolicy-sample-generator --config-file etc/watcher/oslo-policy-generator/watcher-policy-generator.conf
[flake8]
filename = *.py,app.wsgi
show-source=True

View File

@ -0,0 +1,37 @@
# 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.
import itertools
from watcher.common.policies import action
from watcher.common.policies import action_plan
from watcher.common.policies import audit
from watcher.common.policies import audit_template
from watcher.common.policies import base
from watcher.common.policies import goal
from watcher.common.policies import scoring_engine
from watcher.common.policies import service
from watcher.common.policies import strategy
def list_rules():
return itertools.chain(
base.list_rules(),
action.list_rules(),
action_plan.list_rules(),
audit.list_rules(),
audit_template.list_rules(),
goal.list_rules(),
scoring_engine.list_rules(),
service.list_rules(),
strategy.list_rules(),
)

View File

@ -0,0 +1,57 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
ACTION = 'action:%s'
rules = [
policy.DocumentedRuleDefault(
name=ACTION % 'detail',
check_str=base.RULE_ADMIN_API,
description='Retrieve a list of actions with detail.',
operations=[
{
'path': '/v1/actions/detail',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=ACTION % 'get',
check_str=base.RULE_ADMIN_API,
description='Retrieve information about a given action.',
operations=[
{
'path': '/v1/actions/{action_id}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=ACTION % 'get_all',
check_str=base.RULE_ADMIN_API,
description='Retrieve a list of all actions.',
operations=[
{
'path': '/v1/actions',
'method': 'GET'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,79 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
ACTION_PLAN = 'action_plan:%s'
rules = [
policy.DocumentedRuleDefault(
name=ACTION_PLAN % 'delete',
check_str=base.RULE_ADMIN_API,
description='Delete an action plan.',
operations=[
{
'path': '/v1/action_plans/{action_plan_uuid}',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name=ACTION_PLAN % 'detail',
check_str=base.RULE_ADMIN_API,
description='Retrieve a list of action plans with detail.',
operations=[
{
'path': '/v1/action_plans/detail',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=ACTION_PLAN % 'get',
check_str=base.RULE_ADMIN_API,
description='Get an action plan.',
operations=[
{
'path': '/v1/action_plans/{action_plan_id}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=ACTION_PLAN % 'get_all',
check_str=base.RULE_ADMIN_API,
description='Get all action plans.',
operations=[
{
'path': '/v1/action_plans',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=ACTION_PLAN % 'update',
check_str=base.RULE_ADMIN_API,
description='Update an action plans.',
operations=[
{
'path': '/v1/action_plans/{action_plan_uuid}',
'method': 'PATCH'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,90 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
AUDIT = 'audit:%s'
rules = [
policy.DocumentedRuleDefault(
name=AUDIT % 'create',
check_str=base.RULE_ADMIN_API,
description='Create a new audit.',
operations=[
{
'path': '/v1/audits',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT % 'delete',
check_str=base.RULE_ADMIN_API,
description='Delete an audit.',
operations=[
{
'path': '/v1/audits/{audit_uuid}',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT % 'detail',
check_str=base.RULE_ADMIN_API,
description='Retrieve audit list with details.',
operations=[
{
'path': '/v1/audits/detail',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT % 'get',
check_str=base.RULE_ADMIN_API,
description='Get an audit.',
operations=[
{
'path': '/v1/audits/{audit_uuid}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT % 'get_all',
check_str=base.RULE_ADMIN_API,
description='Get all audits.',
operations=[
{
'path': '/v1/audits',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT % 'update',
check_str=base.RULE_ADMIN_API,
description='Update an audit.',
operations=[
{
'path': '/v1/audits/{audit_uuid}',
'method': 'PATCH'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,90 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
AUDIT_TEMPLATE = 'audit_template:%s'
rules = [
policy.DocumentedRuleDefault(
name=AUDIT_TEMPLATE % 'create',
check_str=base.RULE_ADMIN_API,
description='Create an audit template.',
operations=[
{
'path': '/v1/audit_templates',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT_TEMPLATE % 'delete',
check_str=base.RULE_ADMIN_API,
description='Delete an audit template.',
operations=[
{
'path': '/v1/audit_templates/{audit_template_uuid}',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT_TEMPLATE % 'detail',
check_str=base.RULE_ADMIN_API,
description='Retrieve a list of audit templates with details.',
operations=[
{
'path': '/v1/audit_templates/detail',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT_TEMPLATE % 'get',
check_str=base.RULE_ADMIN_API,
description='Get an audit template.',
operations=[
{
'path': '/v1/audit_templates/{audit_template_uuid}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT_TEMPLATE % 'get_all',
check_str=base.RULE_ADMIN_API,
description='Get a list of all audit templates.',
operations=[
{
'path': '/v1/audit_templates',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=AUDIT_TEMPLATE % 'update',
check_str=base.RULE_ADMIN_API,
description='Update an audit template.',
operations=[
{
'path': '/v1/audit_templates/{audit_template_uuid}',
'method': 'PATCH'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,32 @@
# 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.
from oslo_policy import policy
RULE_ADMIN_API = 'rule:admin_api'
ROLE_ADMIN_OR_ADMINISTRATOR = 'role:admin or role:administrator'
ALWAYS_DENY = '!'
rules = [
policy.RuleDefault(
name='admin_api',
check_str=ROLE_ADMIN_OR_ADMINISTRATOR
),
policy.RuleDefault(
name='show_password',
check_str=ALWAYS_DENY
)
]
def list_rules():
return rules

View File

@ -0,0 +1,57 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
GOAL = 'goal:%s'
rules = [
policy.DocumentedRuleDefault(
name=GOAL % 'detail',
check_str=base.RULE_ADMIN_API,
description='Retrieve a list of goals with detail.',
operations=[
{
'path': '/v1/goals/detail',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name=GOAL % 'get',
check_str=base.RULE_ADMIN_API,
description='Get a goal.',
operations=[
{
'path': '/v1/goals/{goal_uuid}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=GOAL % 'get_all',
check_str=base.RULE_ADMIN_API,
description='Get all goals.',
operations=[
{
'path': '/v1/goals',
'method': 'GET'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,66 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
SCORING_ENGINE = 'scoring_engine:%s'
rules = [
# FIXME(lbragstad): Find someone from watcher to double check this
# information. This API isn't listed in watcher's API reference
# documentation.
policy.DocumentedRuleDefault(
name=SCORING_ENGINE % 'detail',
check_str=base.RULE_ADMIN_API,
description='List scoring engines with details.',
operations=[
{
'path': '/v1/scoring_engines/detail',
'method': 'GET'
}
]
),
# FIXME(lbragstad): Find someone from watcher to double check this
# information. This API isn't listed in watcher's API reference
# documentation.
policy.DocumentedRuleDefault(
name=SCORING_ENGINE % 'get',
check_str=base.RULE_ADMIN_API,
description='Get a scoring engine.',
operations=[
{
'path': '/v1/scoring_engines/{scoring_engine_id}',
'method': 'GET'
}
]
),
# FIXME(lbragstad): Find someone from watcher to double check this
# information. This API isn't listed in watcher's API reference
# documentation.
policy.DocumentedRuleDefault(
name=SCORING_ENGINE % 'get_all',
check_str=base.RULE_ADMIN_API,
description='Get all scoring engines.',
operations=[
{
'path': '/v1/scoring_engines',
'method': 'GET'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,57 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
SERVICE = 'service:%s'
rules = [
policy.DocumentedRuleDefault(
name=SERVICE % 'detail',
check_str=base.RULE_ADMIN_API,
description='List services with detail.',
operations=[
{
'path': '/v1/services/',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=SERVICE % 'get',
check_str=base.RULE_ADMIN_API,
description='Get a specific service.',
operations=[
{
'path': '/v1/services/{service_id}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=SERVICE % 'get_all',
check_str=base.RULE_ADMIN_API,
description='List all services.',
operations=[
{
'path': '/v1/services/',
'method': 'GET'
}
]
),
]
def list_rules():
return rules

View File

@ -0,0 +1,57 @@
# 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.
from oslo_policy import policy
from watcher.common.policies import base
STRATEGY = 'strategy:%s'
rules = [
policy.DocumentedRuleDefault(
name=STRATEGY % 'detail',
check_str=base.RULE_ADMIN_API,
description='List strategies with detail.',
operations=[
{
'path': '/v1/strategies/detail',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=STRATEGY % 'get',
check_str=base.RULE_ADMIN_API,
description='Get a strategy.',
operations=[
{
'path': '/v1/strategies/{strategy_uuid}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=STRATEGY % 'get_all',
check_str=base.RULE_ADMIN_API,
description='List all strategies.',
operations=[
{
'path': '/v1/strategies',
'method': 'GET'
}
]
)
]
def list_rules():
return rules

View File

@ -15,11 +15,13 @@
"""Policy Engine For Watcher."""
import sys
from oslo_config import cfg
from oslo_policy import policy
from watcher.common import exception
from watcher.common import policies
_ENFORCER = None
CONF = cfg.CONF
@ -56,6 +58,7 @@ def init(policy_file=None, rules=None,
default_rule=default_rule,
use_conf=use_conf,
overwrite=overwrite)
_ENFORCER.register_defaults(policies.list_rules())
return _ENFORCER
@ -92,3 +95,23 @@ def enforce(context, rule=None, target=None,
'user_id': context.user_id}
return enforcer.enforce(rule, target, credentials,
do_raise=do_raise, exc=exc, *args, **kwargs)
def get_enforcer():
# This method is for use by oslopolicy CLI scripts. Those scripts need the
# 'output-file' and 'namespace' options, but having those in sys.argv means
# loading the Watcher config options will fail as those are not expected
# to be present. So we pass in an arg list with those stripped out.
conf_args = []
# Start at 1 because cfg.CONF expects the equivalent of sys.argv[1:]
i = 1
while i < len(sys.argv):
if sys.argv[i].strip('-') in ['namespace', 'output-file']:
i += 2
continue
conf_args.append(sys.argv[i])
i += 1
cfg.CONF(conf_args, project='watcher')
init()
return _ENFORCER