From 83b08b3aa66ddc729bfbcd4ca78c35de55344543 Mon Sep 17 00:00:00 2001 From: Tomi Juvonen Date: Fri, 17 May 2019 16:51:30 +0300 Subject: [PATCH] Add DevStack plugin Adding what is needed to have Fenix running in DevStack Default workflow dependent configuration needs to be documented Separately. Those might be ssh capability for Fenix service user and AODH configuration. Test case should also add those in future. story: 2005166 Task: #29900 Change-Id: Ifb6602b67f098bcffdc2c03c31fdf868ab61b653 Signed-off-by: Tomi Juvonen --- devstack/plugin.sh | 121 +++++++++++++++++++++++++++++++++++ devstack/settings | 29 +++++++++ fenix/cmd/__init__.py | 0 fenix/utils/identity_auth.py | 51 +++++++++------ fenix/utils/service.py | 11 +--- fenix/workflow/workflow.py | 4 +- setup.cfg | 9 +++ 7 files changed, 193 insertions(+), 32 deletions(-) create mode 100644 devstack/plugin.sh create mode 100644 devstack/settings create mode 100644 fenix/cmd/__init__.py diff --git a/devstack/plugin.sh b/devstack/plugin.sh new file mode 100644 index 0000000..bb8fcda --- /dev/null +++ b/devstack/plugin.sh @@ -0,0 +1,121 @@ +# plugin.sh - DevStack plugin.sh dispatch script fenix + +function install_fenix { + git_clone $FENIX_REPO $FENIX_DIR $FENIX_BRANCH + setup_develop $FENIX_DIR +} + +function init_fenix { + recreate_database fenix utf8 +} + +function configure_fenix { + if [[ ! -d $FENIX_CONF_DIR ]]; then + sudo mkdir -p $FENIX_CONF_DIR + fi + sudo chown $STACK_USER $FENIX_CONF_DIR + touch $FENIX_CONF_FILE + touch $FENIX_API_CONF_FILE + + create_service_user "$FENIX_USER_NAME" "admin" + init_fenix_service_user_conf + + iniset $FENIX_CONF_FILE DEFAULT host "$FENIX_SERVICE_HOST" + iniset $FENIX_API_CONF_FILE DEFAULT host "$FENIX_SERVICE_HOST" + iniset $FENIX_CONF_FILE DEFAULT port "$FENIX_SERVICE_PORT" + iniset $FENIX_API_CONF_FILE DEFAULT port "$FENIX_SERVICE_PORT" + iniset $FENIX_CONF_FILE DEFAULT transport_url $(get_notification_url) + iniset $FENIX_API_CONF_FILE transport_url $(get_notification_url) + + iniset FENIX_CONF_FILE database connection `database_connection_url fenix` +} + +function init_fenix_service_user_conf { + iniset $FENIX_CONF_FILE service_user os_auth_url "$KEYSTONE_SERVICE_URI" + iniset $FENIX_CONF_FILE service_user os_username "$FENIX_USER_NAME" + iniset $FENIX_CONF_FILE service_user os_password "$SERVICE_PASSWORD" + iniset $FENIX_CONF_FILE service_user os_user_domain_name "$SERVICE_DOMAIN_NAME" + iniset $FENIX_CONF_FILE service_user os_project_name "$SERVICE_TENANT_NAME" + iniset $FENIX_CONF_FILE service_user os_project_domain_name "$SERVICE_DOMAIN_NAME" +} + +function create_fenix_accounts { + SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }") + ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }") + + FENIX_USER_ID=$(get_or_create_user $FENIX_USER_NAME \ + "$SERVICE_PASSWORD" "default" "fenix@example.com") + get_or_add_user_project_role $ADMIN_ROLE $FENIX_USER_ID $SERVICE_TENANT + + fenix_api_url="$FENIX_SERVICE_PROTOCOL://$FENIX_SERVICE_HOST:$FENIX_SERVICE_PORT" + + FENIX_SERVICE=$(get_or_create_service "fenix" \ + "maintenance" "Fenix maintenance Service") + get_or_create_endpoint $FENIX_SERVICE \ + "$REGION_NAME" \ + "$fenix_api_url/v1" + + KEYSTONEV3_SERVICE=$(get_or_create_service "keystonev3" \ + "identityv3" "Keystone Identity Service V3") + get_or_create_endpoint $KEYSTONEV3_SERVICE \ + "$REGION_NAME" \ + "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v3" \ + "$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v3" \ + "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v3" +} + +function start_fenix { + run_process fenix-api "$FENIX_BIN_DIR/fenix-api --debug --config-file $FENIX_API_CONF_FILE" + run_process fenix-engine "$FENIX_BIN_DIR/fenix-engine --debug --config-file $FENIX_CONF_FILE" +} + +function stop_fenix { + for serv in fenix-api fenix-engine; do + stop_process $serv + done +} + +function cleanup_fenix { + stop_process "fenix-api" + stop_process "fenix-engine" +} + +# check for service enabled +if is_service_enabled fenix-api && is_service_enabled fenix-engine; then + + if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then + # Set up system services + echo_summary "Pre installation for Fenix" + + elif [[ "$1" == "stack" && "$2" == "install" ]]; then + # Perform installation of service source + echo_summary "Installing Fenix" + install_fenix + + elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then + # Configure after the other layer 1 and 2 services have been configured + echo_summary "Configuring Fenix" + configure_fenix + create_fenix_accounts + + elif [[ "$1" == "stack" && "$2" == "extra" ]]; then + # Initialize and start the fenix service + echo_summary "Initializing Fenix" + init_fenix + start_fenix + fi + + if [[ "$1" == "unstack" ]]; then + # Shut down fenix services + # no-op + stop_fenix + fi + + if [[ "$1" == "clean" ]]; then + # Remove state and transient data + # Remember clean.sh first calls unstack.sh + # no-op + echo_summary "Clean Fenix" + fi + +fi diff --git a/devstack/settings b/devstack/settings new file mode 100644 index 0000000..437fc20 --- /dev/null +++ b/devstack/settings @@ -0,0 +1,29 @@ +# Defaults +# -------- + +define_plugin fenix + +#enable Fenix engine service +enable_service fenix-engine + +#enable Fenix api service +enable_service fenix-api + +FENIX_USER_NAME=${FENIX_USER_NAME:-fenix} + +# Set up default repos +FENIX_REPO=${FENIX_REPO:-${GIT_BASE}/openstack/fenix.git} +FENIX_BRANCH=${FENIX_BRANCH:-master} + +# Set up default directories +FENIX_DIR=$DEST/fenix +FENIX_CONF_DIR=${FENIX_CONF_DIR:-/etc/fenix} +FENIX_CONF_FILE=$FENIX_CONF_DIR/fenix.conf +FENIX_API_CONF_FILE=$FENIX_CONF_DIR/fenix-api.conf +FENIX_BIN_DIR=$(get_python_exec_prefix) + +FENIX_SERVICE_HOST=${FENIX_SERVICE_HOST:-$SERVICE_HOST} +FENIX_SERVICE_PORT=${FENIX_SERVICE_PORT:-12347} +FENIX_SERVICE_PROTOCOL=${FENIX_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL} + +# Fenix specific configurations diff --git a/fenix/cmd/__init__.py b/fenix/cmd/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fenix/utils/identity_auth.py b/fenix/utils/identity_auth.py index 328be32..910eb36 100644 --- a/fenix/utils/identity_auth.py +++ b/fenix/utils/identity_auth.py @@ -12,35 +12,46 @@ # 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 os from keystoneauth1 import loading from keystoneauth1 import session +from oslo_config import cfg -def get_identity_auth(username=None, password=None, project=None): - auth_url = os.environ['OS_AUTH_URL'] - username = username or os.environ['OS_USERNAME'] - password = password or os.environ['OS_PASSWORD'] - user_domain_name = os.environ.get('OS_USER_DOMAIN_NAME') or 'Default' - user_domain_id = os.environ.get('OS_USER_DOMAIN_ID') or 'default' - project_name = (project or os.environ.get('OS_PROJECT_NAME') or - os.environ.get('OS_TENANT_NAME')) - project_domain_name = os.environ.get('OS_PROJECT_DOMAIN_NAME') or 'Default' - project_domain_id = os.environ.get('OS_PROJECT_DOMAIN_ID') or 'default' +os_opts = [ + cfg.StrOpt('os_auth_url', + default=os.environ.get('OS_AUTH_URL', ''), + help='OpenStack Identity service URL.'), + cfg.StrOpt('os_username', + default=os.environ.get('OS_USERNAME', 'fenix'), + help='Fenix user. Must have admin role'), + cfg.StrOpt('os_password', + default=os.environ.get('OS_PASSWORD', 'fenix'), + help='Fenix admin user password'), + cfg.StrOpt('os_user_domain_name', + default=os.environ.get('OS_USER_DOMAIN_NAME', 'default'), + help='A domain name the os_username belongs to.'), + cfg.StrOpt('os_project_name', + default=os.environ.get('OS_PROJECT_NAME', + os.environ.get('OS_TENANT_NAME')), + help='the Fenix admin project'), + cfg.StrOpt('os_project_domain_name', + default=os.environ.get('OS_PROJECT_DOMAIN_NAME', 'default'), + help='the Fenix admin project domain') +] + +def get_identity_auth(conf): loader = loading.get_plugin_loader('password') return loader.load_from_options( - auth_url=auth_url, - username=username, - password=password, - user_domain_name=user_domain_name, - user_domain_id=user_domain_id, - project_name=project_name, - tenant_name=project_name, - project_domain_name=project_domain_name, - project_domain_id=project_domain_id) + auth_url=conf.service_user.os_auth_url, + username=conf.service_user.os_username, + password=conf.service_user.os_password, + user_domain_name=conf.service_user.os_user_domain_name, + project_name=conf.service_user.os_project_name, + tenant_name=conf.service_user.os_project_name, + project_domain_name=conf.service_user.os_project_domain_name) def get_session(auth=None): diff --git a/fenix/utils/service.py b/fenix/utils/service.py index 08d37ad..9849946 100644 --- a/fenix/utils/service.py +++ b/fenix/utils/service.py @@ -37,6 +37,7 @@ from uuid import uuid1 as generate_uuid from fenix import context from fenix.utils.download import download_url +import fenix.utils.identity_auth MAX_SESSIONS = 3 @@ -51,15 +52,6 @@ opts = [ cfg.IntOpt('port', default=5000, help="API port to use."), - cfg.StrOpt('workflow_user', - default=os.environ.get('OS_USERNAME', 'admin'), - help="API host IP"), - cfg.StrOpt('workflow_password', - default=os.environ.get('OS_PASSWORD', 'admin'), - help="API host IP"), - cfg.StrOpt('workflow_project', - default=os.environ.get('OS_PROJECT_NAME', 'admin'), - help="API host IP"), cfg.IntOpt('project_maintenance_reply', default=40, help="Project maintenance reply confirmation time in seconds"), @@ -77,6 +69,7 @@ opts = [ help="How long to wait live migration to be done"), ] +CONF.register_opts(fenix.utils.identity_auth.os_opts, group='service_user') CONF.register_opts(opts) diff --git a/fenix/workflow/workflow.py b/fenix/workflow/workflow.py index 49e43e5..cf28dc6 100644 --- a/fenix/workflow/workflow.py +++ b/fenix/workflow/workflow.py @@ -69,9 +69,7 @@ class BaseWorkflow(Thread): 'MAINTENANCE_DONE': 'maintenance_done', 'MAINTENANCE_FAILED': 'maintenance_failed'} self.url = "http://%s:%s" % (conf.host, conf.port) - self.auth = get_identity_auth(conf.workflow_user, - conf.workflow_password, - conf.workflow_project) + self.auth = get_identity_auth(conf) self.auth_session = get_session(auth=self.auth) self.aodh = aodhclient.Client('2', self.auth_session) transport = messaging.get_transport(self.conf) diff --git a/setup.cfg b/setup.cfg index 681b496..5c3b31f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,10 +19,19 @@ classifier = Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 +[global] +setup-hooks = pbr.hooks.setup_hook + [files] packages = fenix +[entry_points] +console_scripts = + fenix-db-manage=fenix.db.migration.cli:main + fenix-api=fenix.cmd.api:main + fenix-engine=fenix.cmd.engine:main + [compile_catalog] directory = fenix/locale domain = fenix