config/devstack/lib/config
Joao Victor Portal 9aee309999 Deprecate old policy engine and restrict access
This commit does two different changes: it changes the policy engine to
oslo_policy and restrict access to sysinv API to users of projects
'admin' or 'services'.

The policy engine deprecated is the one present in the file
"sysinv/sysinv/sysinv/sysinv/openstack/common/policy.py" (780 lines).
This file is no longer used by this repository and was not deleted
because it is used by other repositories, like starlingx/update. The
library oslo_policy is used in its place. In fact, the deprecated engine
seems to be an ancient version of oslo_policy. The library oslo_policy
changed the default format of configuration files from JSON to YAML, so
the configuration files named "policy.json" were changed to
"policy.yaml". The file that initializes and wraps oslo_policy
("sysinv/sysinv/sysinv/sysinv/common/policy.py") contains the minimal
implementation to use this library.

The access to sysinv API, before this commit, was restricted to users
with role "admin" or "administrator" from any project. This commit
restricts the access to users with role "admin" of projects "admin" or
"services". This change should not cause problems, because role
"administrator" doesn't exist and because all users from Starlingx are
from projects "admin" or "services". This change is needed to avoid
access from admin users of other projects.

To test custom policy rules set in the file "/etc/sysinv/policy.yaml",
it will be used the Service Parameter API actions create/apply/modify/
delete/get (commands "system service-parameter-[add/apply/modify/delete/
list]". To test default policy for sysinv API commands, it will be used
the command to change the system description (PATCH "/v1/isystems",
command "system modify --description='test'"). On test plan, these
commands will be reffered as "test commands". Any change in the file
"/etc/sysinv/policy.yaml" is detected by policy engine and rules are
updated.

Test Plan:

PASS: Successfully deploy an AIO-SX using an Debian image with this
commit present. Successfully create, through openstack CLI, the users:
'testreader' with role 'reader' in project 'admin',
'adminsvc' with role 'admin' in project 'services' and
'otheradmin' with role 'admin' in project 'notadminproject'.
Create openrc files for all new users. Note: the other user that will be
used is the already existing 'admin' with role 'admin' in project
'admin'.
PASS: In the deployed AIO-SX, check the behavior of test commands
through different users: for "admin" and "adminsvc" users, all commands
are successful; for user "testreader", only "service-parameter-list"
command is successful and for user "otheradmin" no command is
successful.
PASS: In the deployed AIO-SX, add the following lines in file
"/etc/sysinv/policy.yaml":
config_api:service_parameter:add: role:reader
config_api:service_parameter:apply: role:reader
config_api:service_parameter:delete: role:reader
config_api:service_parameter:get: role:reader
config_api:service_parameter:modify: role:reader
and check the behavior of test commands through different users:
for "admin" and "adminsvc" users, all commands are successful; for users
"testreader" and "otheradmin", all commands are successful except the
change in the system description ("system modify --description='test'").
PASS: In the deployed AIO-SX, to assert that public API works without
authentication, execute the commands:
"curl -v http://<MGMT_IP>:6385/v1/" and
"curl -v http://<MGMT_IP>:6385/v1/isystems/mgmtvlan" and
verify that they are accepted and that the HTTP response is 200,
and execute the commands:
"curl -v http://<MGMT_IP>:6385/v1/isystems/" and
"curl -v http://<MGMT_IP>:6385/v1/service_parameter" and
verify that they are rejected and that the HTTP response is 401.
PASS: Repeat all tests above changing the deploy to AIO-DX using an
CentOS image.
PASS: Successfully execute Debian AIO-SX daily regression and sanity
tests using an image containing this change.

Story: 2010149
Task: 45984

Signed-off-by: Joao Victor Portal <Joao.VictorPortal@windriver.com>
Change-Id: Id7aa387e154afb1441a8484b076cdc97f2fc46cb
2022-08-10 11:18:38 -03:00

350 lines
12 KiB
Bash

#!/bin/bash
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2019 Intel Corporation
#
# Copyright (c) 2021 Wind River Systems, Inc.
#
# lib/config
# Functions to control the configuration and operation of stx-config
# Dependencies:
#
# - ``functions`` file
# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
# - The update and fault plugins must be enabled
# ``stack.sh`` calls the entry points in this order:
#
# - install_config
# - configure_config
# - init_config
# - start_config
# - stop_config
# - cleanup_config
_XTRACE_STX_CONFIG=$(set +o | grep xtrace)
set -o xtrace
# Defaults
# --------
STX_CONFIG_DIR=${GITDIR[$STX_CONFIG_NAME]}
STX_SYSCONFDIR=${STX_SYSCONFDIR:-/etc}
# Set up GITDIR so setup_lib and setup_dev_lib work properly
GITDIR["cgts-client"]=$STX_CONFIG_DIR/sysinv/cgts-client/cgts-client
STX_CTRL_CONF_DIR=$STX_CONFIG_DIR/controllerconfig/controllerconfig
SYSINV_DIR=$STX_CONFIG_DIR/sysinv/sysinv/sysinv
SYSINV_AGENT_DIR=$STX_CONFIG_DIR/sysinv/sysinv-agent
SYSINV_CONF_DIR=$STX_SYSCONFDIR/sysinv
SYSINV_CONF_FILE=$SYSINV_CONF_DIR/sysinv.conf
SYSINV_SERVICE_PROTOCOL=${SYSINV_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
SYSINV_SERVICE_PORT=${SYSINV_SERVICE_PORT:-6385}
SYSINV_SERVICE_HOST=${SYSINV_SERVICE_HOST:-$SERVICE_HOST}
SYSINV_ETC_GOENABLEDD=/etc/goenabled.d
SYSINV_API_PASTE_INI=$SYSINV_CONF_DIR/api-paste.ini
SYSINV_ETC_MOTDD=/etc/motd.d
SYSINV_API_PORT=$SYSINV_SERVICE_PORT
SYSINV_AUTH_STRATEGY=${SYSINV_AUTH_STRATEGY:-keystone}
SYSINV_AUTH_CACHE_DIR=${SYSINV_AUTH_CACHE_DIR:-/var/cache/sysinv}
# STX_INST_DIR should be a non-root-writable place to install build artifacts
STX_INST_DIR=${STX_INST_DIR:-/usr/local}
STX_BIN_DIR=${STX_BIN_DIR:-$STX_INST_DIR/bin}
STX_SBIN_DIR=${STX_SBIN_DIR:-$STX_INST_DIR/sbin}
# Set up so we don't use sudo for installs when not necessary
STX_SUDO="sudo"
[[ -w $STX_INST_DIR ]] && STX_SUDO="env"
PYTHON_SITE_DIR=$(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
STX_OCF_ROOT=${STX_OCF_ROOT:-/usr/lib/ocf}
# Functions
# ---------
function check_sysinv_services {
local stx_services="sysinv-api sysinv-cond sysinv-agent"
local service
for service in $stx_services; do
if [[is_service_enabled $service && $SYSTEMCTL is-enabled devstack@$service.service]]; then
$SYSTEMCTL status devstack@$service.service --no-pager
fi
done
}
function cleanup_cgtsclient {
pip_uninstall cgtsclient
}
function cleanup_config {
if is_service_enabled sysinv; then
cleanup_sysinv
cleanup_controllerconfig
fi
if is_service_enabled cgtsclient; then
cleanup_cgtsclient
fi
}
function cleanup_controllerconfig {
pip_uninstall controllerconfig
sudo rm -f /etc/bash_completion.d/system.bash_completion
}
function cleanup_sysinv {
stop_sysinv
pip_uninstall sysinv
sudo rm -f $SYSINV_ETC_GOENABLEDD/sysinv_goenabled_check.sh
sudo rm -f $SYSINV_CONF_DIR/policy.yaml
sudo rm -f $SYSINV_ETC_MOTDD/10-system
sudo rm -f $SYSINV_CONF_DIR/upgrades/delete_load.sh
sudo rm -f $STX_OCF_ROOT/resource.d/platform/sysinv-api
sudo rm -f $STX_OCF_ROOT/resource.d/platform/sysinv-conductor
sudo rm -f $STX_SYSCONFDIR/systemd/system/sysinv-api.service
sudo rm -f $STX_SYSCONFDIR/systemd/system/sysinv-conductor.service
sudo rm -f $STX_BIN_DIR/partition_info.sh
sudo rm -f $STX_BIN_DIR/manage-partitions
sudo rm -f $STX_BIN_DIR/query_pci_id
sudo rm -rf $SYSINV_AUTHO_CACHE_DIR $SYSINV_CONF_DIR
}
function configure_config {
if is_service_enabled sysinv; then
configure_sysinv
create_sysinv_user_group
create_sysinv_accounts
fi
}
function configure_sysinv {
sudo install -d -o $STACK_USER $SYSINV_CONF_DIR
cp $SYSINV_DIR/etc/sysinv/sysinv.conf.sample $SYSINV_CONF_FILE
iniset $SYSINV_CONF_FILE DEFAULT MTC_INV_LABLE /v1/hosts/
iniset $SYSINV_CONF_FILE DEFAULT sysinv_api_port $SYSINV_API_PORT
iniset $SYSINV_CONF_FILE DEFAULT use_syslog True
iniset $SYSINV_CONF_FILE DEFAULT rabbit_host $RABBIT_HOST
iniset $SYSINV_CONF_FILE DEFAULT rabbit_hosts $RABBIT_HOST:5672
iniset $SYSINV_CONF_FILE DEFAULT rabbit_port 5672
iniset $SYSINV_CONF_FILE DEFAULT verbose True
iniset $SYSINV_CONF_FILE DEFAULT sysinv_api_bind_ip $HOST_IP
iniset $SYSINV_CONF_FILE DEFAULT auth_strategy $SYSINV_AUTH_STRATEGY
iniset $SYSINV_CONF_FILE DEFAULT control_exchange openstack
iniset $SYSINV_CONF_FILE DEFAULT rabbit_userid $RABBIT_USERID
iniset $SYSINV_CONF_FILE DEFAULT rabbit_virtual_host /
iniset $SYSINV_CONF_FILE DEFAULT api_paste_config $CINDER_API_PASTE_INI
iniset $SYSINV_CONF_FILE DEFAULT debug True
iniset $SYSINV_CONF_FILE DEFAULT rabbit_password $RABBIT_PASSWORD
# transport_url is not in config files, so we don't need call iniset_rpc_backend
# iniset_rpc_backend sysinv $SYSINV_CONF_FILE
iniset $SYSINV_CONF_FILE DEFAULT rabbit_ha_queues False
setup_logging $SYSINV_CONF_FILE
configure_auth_token_middleware $SYSINV_CONF_FILE sysinv $SYSINV_AUTH_CACHE_DIR/api
iniset $SYSINV_CONF_FILE database connection `database_connection_url sysinv`
}
function create_sysinv_accounts {
get_or_create_service "sysinv" "platform" "SysInv services"
create_service_user "sysinv" "admin"
sysinv_api_url="$SYSINV_SERVICE_PROTOCOL://$SYSINV_SERVICE_HOST:$SYSINV_SERVICE_PORT"
get_or_create_endpoint \
"sysinv" \
"$REGION_NAME" \
"$sysinv_api_url/v1"
}
# create_sysinv_cache_dir() - Part of the init_sysinv() process
function create_sysinv_cache_dir {
# Create cache dir
sudo mkdir -p $SYSINV_AUTH_CACHE_DIR/api
sudo chown $STACK_USER $SYSINV_AUTH_CACHE_DIR/api
rm -f $SYSINV_AUTH_CACHE_DIR/api/*
sudo mkdir -p $SYSINV_AUTH_CACHE_DIR/registry
sudo chown $STACK_USER $SYSINV_AUTH_CACHE_DIR/registry
rm -f $SYSINV_AUTH_CACHE_DIR/registry/*
}
function create_sysinv_user_group {
if ! getent group sysinv >/dev/null; then
sudo groupadd sysinv
fi
if ! getent passwd sysinv >/dev/null; then
sudo mkdir -p /home/sysinv
sudo useradd -g sysinv -s /bin/bash -d /home/sysinv -m sysinv
echo "Giving user sysinv passwordless sudo privileges"
# UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
sudo echo "#includedir /etc/sudoers.d" >> /etc/sudoers
# Set up DevStack sudoers
TEMPFILE=`mktemp`
echo "sysinv ALL=(root) NOPASSWD:ALL" >$TEMPFILE
# Some binaries might be under ``/sbin`` or ``/usr/sbin``, so make sure sudo will
# see them by forcing ``PATH``
echo "Defaults:sysinv secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
echo "Defaults:sysinv !requiretty" >> $TEMPFILE
chmod 0440 $TEMPFILE
sudo chown root:root $TEMPFILE
sudo mv $TEMPFILE /etc/sudoers.d/60_sysinv_sh
fi
}
function init_config {
if is_service_enabled sysinv; then
# Migrations need this
sudo install -d -m 755 -o ${USER} /var/run/sysinv
if [[ "$HOST_TOPOLOGY_ROLE" != "subnode" ]]; then
# (Re)create sysinv database
echo "recreate_database sysinv and dbsync"
recreate_database sysinv
$STX_BIN_DIR/sysinv-dbsync --config-file=$SYSINV_CONF_FILE
fi
create_sysinv_cache_dir
fi
}
function install_cgtsclient {
setup_dev_lib "cgts-client"
sudo install -D -m 0644 -o $STACK_USER {${GITDIR["cgts-client"]}/tools/,/etc/bash_completion.d/}system.bash_completion
}
function install_config {
if is_service_enabled cgtsclient; then
install_cgtsclient
fi
if is_service_enabled sysinv; then
install_controllerconfig
install_sysinv
fi
if is_service_enabled sysinv-agent; then
install_sysinv_agent
fi
}
function install_controllerconfig {
# This is a hack to work around the lack of proper global-requirements
# setup in these packages
pip_install pycrypto
# We can't use setup_develop as there is no setup.cfg file present for controllerconfig
setup_package $STX_CTRL_CONF_DIR -e
}
function install_sysinv {
setup_develop $SYSINV_DIR
sudo install -d -m 755 $SYSINV_ETC_GOENABLEDD
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/sysinv_goenabled_check.sh $SYSINV_ETC_GOENABLEDD/sysinv_goenabled_check.sh
sudo install -d -m 755 $SYSINV_CONF_DIR
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/policy.yaml $SYSINV_CONF_DIR/policy.yaml
sudo install -d -m 755 $SYSINV_ETC_MOTDD
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/motd-system $SYSINV_ETC_MOTDD/10-system
sudo install -d -m 755 $SYSINV_CONF_DIR/upgrades
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/delete_load.sh $SYSINV_CONF_DIR/upgrades/delete_load.sh
sudo install -p -D -m 755 $SYSINV_DIR/scripts/sysinv-api $STX_OCF_ROOT/resource.d/platform/sysinv-api
sudo install -p -D -m 755 $SYSINV_DIR/scripts/sysinv-conductor $STX_OCF_ROOT/resource.d/platform/sysinv-conductor
sudo install -p -D -m 755 $SYSINV_DIR/scripts/sysinv-api.service $STX_SYSCONFDIR/systemd/system/sysinv-api.service
sudo install -p -D -m 755 $SYSINV_DIR/scripts/sysinv-conductor.service $STX_SYSCONFDIR/systemd/system/sysinv-conductor.service
sudo install -d -m 755 $STX_BIN_DIR
sudo install -p -D -m 755 $SYSINV_DIR/sysinv/cmd/partition_info.sh $STX_BIN_DIR/partition_info.sh
sudo install -p -D -m 755 $SYSINV_DIR/sysinv/cmd/manage-partitions $STX_BIN_DIR/manage-partitions
sudo install -p -D -m 755 $SYSINV_DIR/sysinv/cmd/query_pci_id $STX_BIN_DIR/query_pci_id
}
function install_sysinv_agent {
#rename to sysinv-agent.sh to avoid overwrite entry_point of sysinv-agent
sudo install -p -D -m 755 $SYSINV_AGENT_DIR/sysinv-agent $STX_BIN_DIR/sysinv-agent.sh
}
function start_config {
if is_service_enabled sysinv; then
start_sysinv
fi
}
function start_sysinv {
if is_service_enabled sysinv-api; then
start_sysinv_api
fi
if is_service_enabled sysinv-cond; then
start_sysinv_conductor
fi
if is_service_enabled sysinv-agent; then
start_sysinv_agent
fi
}
function start_sysinv_agent {
run_process sysinv-agent "$STX_BIN_DIR/sysinv-agent"
}
function start_sysinv_api {
run_process sysinv-api "$STX_BIN_DIR/sysinv-api --config-file=$SYSINV_CONF_FILE"
# Get right service port for testing
local service_port=$SYSINV_SERVICE_PORT
local service_protocol=$SYSINV_SERVICE_PROTOCOL
if is_service_enabled tls-proxy; then
service_port=$SYSINV_SERVICE_PORT
service_protocol="http"
fi
echo "Waiting for sysinv-api ($SERVICE_HOST:$service_port) to start..."
if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $service_protocol://$SERVICE_HOST:$service_port/; do sleep 1; done"; then
die $LINENO "sysinv-api did not start"
fi
if is_service_enabled tls-proxy; then
start_tls_proxy sysinv '*' $SYSINV_SERVICE_PORT $SERVICE_HOST $SYSINV_SERVICE_PORT
fi
}
function start_sysinv_conductor {
# the 1st will fail
stop_sysinv_conductor
run_process sysinv-cond "$STX_BIN_DIR/sysinv-conductor --config-file=$SYSINV_CONF_FILE"
# TODO: Find a way to check whether the conductor has started.
# TODO: first run in extra stage will fail, need run second time in test-config
}
function stop_config {
if is_service_enabled sysinv; then
stop_sysinv
fi
}
function stop_sysinv {
if is_service_enabled sysinv-api; then
stop_sysinv_api
fi
if is_service_enabled sysinv-cond; then
stop_sysinv_conductor
fi
if is_service_enabled sysinv-agent; then
stop_sysinv_agent
fi
}
function stop_sysinv_agent {
stop_process sysinv-agent
}
function stop_sysinv_api {
stop_process sysinv-api
}
function stop_sysinv_conductor {
stop_process sysinv-cond
}
$_XTRACE_STX_CONFIG