Name: barbican-bin Namespace: openstack Labels: app.kubernetes.io/managed-by=Helm Annotations: meta.helm.sh/release-name: barbican meta.helm.sh/release-namespace: openstack Data ==== barbican.sh: ---- #!/bin/bash set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/barbican/barbican-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND db-sync.sh: ---- #!/bin/bash set -ex barbican-db-manage upgrade set +x echo "Ensuring that project KEKs are wrapped with the target global KEK" /tmp/simple_crypto_kek_rewrap.py --old-keks="$(cat /tmp/old_keks)" ks-service.sh: ---- #!/bin/bash # Copyright 2017 Pete Birley # # 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. set -ex # Service boilerplate description OS_SERVICE_DESC="${OS_REGION_NAME}: ${OS_SERVICE_NAME} (${OS_SERVICE_TYPE}) service" # Get Service ID if it exists unset OS_SERVICE_ID # FIXME - There seems to be an issue once in a while where the # openstack service list fails and encounters an error message such as: # Unable to establish connection to # https://keystone-api.openstack.svc.cluster.local:5000/v3/auth/tokens: # ('Connection aborted.', OSError("(104, 'ECONNRESET')",)) # During an upgrade scenario, this would cause the OS_SERVICE_ID to be blank # and it would attempt to create a new service when it was not needed. # This duplciate service would sometimes be used by other services such as # Horizon and would give an 'Invalid Service Catalog' error. # This loop allows for a 'retry' of the openstack service list in an # attempt to get the service list as expected if it does ecounter an error. # This loop and recheck can be reverted once the underlying issue is addressed. # If OS_SERVICE_ID is blank then wait a few seconds to give it # additional time and try again for i in $(seq 3) do OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) # If the service was found, go ahead and exit successfully. if [[ -n "${OS_SERVICE_ID}" ]]; then exit 0 fi sleep 2 done # If we've reached this point and a Service ID was not found, # then create the service OS_SERVICE_ID=$(openstack service create -f value -c id \ --name="${OS_SERVICE_NAME}" \ --description "${OS_SERVICE_DESC}" \ --enable \ "${OS_SERVICE_TYPE}") ks-user.sh: ---- #!/bin/bash # Copyright 2017 Pete Birley # # 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. set -ex shopt -s nocasematch if [[ "${SERVICE_OS_PROJECT_DOMAIN_NAME}" == "Default" ]] then PROJECT_DOMAIN_ID="default" else # Manage project domain PROJECT_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Domain for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_PROJECT_DOMAIN_NAME}" \ "${SERVICE_OS_PROJECT_DOMAIN_NAME}") fi if [[ "${SERVICE_OS_USER_DOMAIN_NAME}" == "Default" ]] then USER_DOMAIN_ID="default" else # Manage user domain USER_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Domain for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_USER_DOMAIN_NAME}" \ "${SERVICE_OS_USER_DOMAIN_NAME}") fi shopt -u nocasematch # Manage user project USER_PROJECT_DESC="Service Project for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_PROJECT_DOMAIN_NAME}" USER_PROJECT_ID=$(openstack project create --or-show --enable -f value -c id \ --domain="${PROJECT_DOMAIN_ID}" \ --description="${USER_PROJECT_DESC}" \ "${SERVICE_OS_PROJECT_NAME}"); # Manage user USER_DESC="Service User for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_USER_DOMAIN_NAME}/${SERVICE_OS_SERVICE_NAME}" USER_ID=$(openstack user create --or-show --enable -f value -c id \ --domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ --description="${USER_DESC}" \ "${SERVICE_OS_USERNAME}"); # Manage user password (we do this in a seperate step to ensure the password is updated if required) set +x echo "Setting user password via: openstack user set --password=xxxxxxx ${USER_ID}" openstack user set --password="${SERVICE_OS_PASSWORD}" "${USER_ID}" set -x function ks_assign_user_role () { if [[ "$SERVICE_OS_ROLE" == "admin" ]] then USER_ROLE_ID="$SERVICE_OS_ROLE" else USER_ROLE_ID=$(openstack role create --or-show -f value -c id "${SERVICE_OS_ROLE}"); fi # Manage user role assignment openstack role add \ --user="${USER_ID}" \ --user-domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ "${USER_ROLE_ID}" } # Manage user service role IFS=',' for SERVICE_OS_ROLE in ${SERVICE_OS_ROLES}; do ks_assign_user_role done # Manage user member role : ${MEMBER_OS_ROLE:="member"} export USER_ROLE_ID=$(openstack role create --or-show -f value -c id \ "${MEMBER_OS_ROLE}"); ks_assign_user_role rabbit-init.sh: ---- #!/bin/bash set -e # Extract connection details RABBIT_HOSTNAME=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $1}') RABBIT_PORT=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $2}') # Extract Admin User creadential RABBITMQ_ADMIN_USERNAME=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $4}') RABBITMQ_ADMIN_PASSWORD=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $5}' | \ sed 's/%/\\x/g' | \ xargs -0 printf "%b") # Extract User creadential RABBITMQ_USERNAME=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $4}') RABBITMQ_PASSWORD=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $5}' | \ sed 's/%/\\x/g' | \ xargs -0 printf "%b") # Extract User vHost RABBITMQ_VHOST=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $3}') # Resolve vHost to / if no value is set RABBITMQ_VHOST="${RABBITMQ_VHOST:-/}" function rabbitmqadmin_cli () { if [ -n "$RABBITMQ_X509" ] then rabbitmqadmin \ --ssl \ --ssl-disable-hostname-verification \ --ssl-ca-cert-file="${USER_CERT_PATH}/ca.crt" \ --ssl-cert-file="${USER_CERT_PATH}/tls.crt" \ --ssl-key-file="${USER_CERT_PATH}/tls.key" \ --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} else rabbitmqadmin \ --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} fi } echo "Managing: User: ${RABBITMQ_USERNAME}" rabbitmqadmin_cli \ declare user \ name="${RABBITMQ_USERNAME}" \ password="${RABBITMQ_PASSWORD}" \ tags="user" echo "Deleting Guest User" rabbitmqadmin_cli \ delete user \ name="guest" || true if [ "${RABBITMQ_VHOST}" != "/" ] then echo "Managing: vHost: ${RABBITMQ_VHOST}" rabbitmqadmin_cli \ declare vhost \ name="${RABBITMQ_VHOST}" else echo "Skipping root vHost declaration: vHost: ${RABBITMQ_VHOST}" fi echo "Managing: Permissions: ${RABBITMQ_USERNAME} on ${RABBITMQ_VHOST}" rabbitmqadmin_cli \ declare permission \ vhost="${RABBITMQ_VHOST}" \ user="${RABBITMQ_USERNAME}" \ configure=".*" \ write=".*" \ read=".*" if [ ! -z "$RABBITMQ_AUXILIARY_CONFIGURATION" ] then echo "Applying additional configuration" echo "${RABBITMQ_AUXILIARY_CONFIGURATION}" > /tmp/rmq_definitions.json rabbitmqadmin_cli import /tmp/rmq_definitions.json fi simple_crypto_kek_rewrap.py: ---- #!/usr/bin/env python # 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 argparse import base64 import sys from cryptography import fernet from oslo_db.sqlalchemy import session from sqlalchemy import orm from sqlalchemy.orm import scoping from barbican.common import utils from barbican.model import models from barbican.plugin.crypto import simple_crypto # Use config values from simple_crypto CONF = simple_crypto.CONF class KekRewrap(object): def __init__(self, conf, old_keks): self.dry_run = False self.db_engine = session.create_engine(conf.database.connection) self._session_creator = scoping.scoped_session( orm.sessionmaker( bind=self.db_engine, ) ) self.crypto_plugin = simple_crypto.SimpleCryptoPlugin(conf) self.plugin_name = utils.generate_fullname_for(self.crypto_plugin) if hasattr(self.crypto_plugin, 'master_kek'): self.encryptor = fernet.Fernet(self.crypto_plugin.master_kek) else: self.encryptor = fernet.MultiFernet( [fernet.Fernet(x) for x in self.crypto_plugin.master_keys] ) self.decryptor = fernet.MultiFernet( [fernet.Fernet(x.encode('utf-8')) for x in old_keks] ) def rewrap_kek(self, project, kek): db_begin_fn = self.db_session.begin_nested if ( self.db_session.in_transaction()) else self.db_session.begin with db_begin_fn(): plugin_meta = kek.plugin_meta # try to unwrap with the target kek, and if successful, skip try: if self.encryptor.decrypt(plugin_meta.encode('utf-8')): print('Project KEK {} is already wrapped with target KEK, skipping'.format(kek.id)) return except fernet.InvalidToken: pass # decrypt with the old kek print('Unwrapping Project KEK {}'.format(kek.id)) try: decrypted_plugin_meta = self.decryptor.decrypt(plugin_meta.encode('utf-8')) except fernet.InvalidToken: print('Failed to unwrap Project KEK {}'.format(kek.id)) raise # encrypt with the new kek print('Rewrapping Project KEK {}'.format(kek.id)) try: new_plugin_meta = self.encryptor.encrypt(decrypted_plugin_meta).decode('utf-8') except fernet.InvalidToken: print('Failed to wrap Project KEK {}'.format(kek.id)) raise if self.dry_run: return # Update KEK metadata in DB print('Storing updated Project KEK {}'.format(kek.id)) kek.plugin_meta = new_plugin_meta def get_keks_for_project(self, project): keks = [] db_begin_fn = self.db_session.begin_nested if ( self.db_session.in_transaction()) else self.db_session.begin with db_begin_fn() as transaction: print('Retrieving KEKs for Project {}'.format(project.external_id)) query = transaction.session.query(models.KEKDatum) query = query.filter_by(project_id=project.id) query = query.filter_by(plugin_name=self.plugin_name) keks = query.all() return keks def get_projects(self): print('Retrieving all available projects') projects = [] db_begin_fn = self.db_session.begin_nested if ( self.db_session.in_transaction()) else self.db_session.begin with db_begin_fn() as transaction: projects = transaction.session.query(models.Project).all() return projects @property def db_session(self): return self._session_creator() def execute(self, dry_run=True): self.dry_run = dry_run if self.dry_run: print('-- Running in dry-run mode --') projects = self.get_projects() successes = [] failures = [] for project in projects: keks = self.get_keks_for_project(project) for kek in keks: try: self.rewrap_kek(project, kek) successes.append(kek.id) except Exception: failures.append(kek.id) if successes: print('Sucessfully processed the following KEKs:') print('\n'.join(successes)) if failures: print('Failed to rewrap the following KEKs:') print('\n'.join(failures)) sys.exit(1) def main(): script_desc = 'Utility to re-wrap Project KEKs after rotating the global KEK.' parser = argparse.ArgumentParser(description=script_desc) parser.add_argument( '--dry-run', action='store_true', help='Displays changes that will be made (Non-destructive)' ) parser.add_argument( '--old-keks', default="dGhpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=", help='Old key encryption keys previously used by Simple Crypto Plugin. ' 'A comma separated string of list contain keys ' '( with formate 32 bytes and base64-encoded ). ' 'First key in list is used for ecnrypting new data. ' 'Additional keys used for decrypting existing data.' ) args = parser.parse_args() rewrapper = KekRewrap(CONF, args.old_keks.split(",")) rewrapper.execute(args.dry_run) if __name__ == '__main__': main() barbican-test.sh: ---- #!/bin/bash set -ex openstack secret list # Come up with a random payload PAYLOAD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` echo $PAYLOAD SECRET=`openstack secret store --name mysecret --payload ${PAYLOAD} | awk ' /href/ {print $5}'` openstack secret list openstack secret get $SECRET openstack secret get --payload $SECRET openstack secret delete $SECRET openstack secret list db-drop.py: ---- #!/usr/bin/env python # Drops db and user for an OpenStack Service: # Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain # SQLAlchemy strings for the root connection to the database and the one you # wish the service to use. Alternatively, you can use an ini formatted config # at the location specified by OPENSTACK_CONFIG_FILE, and extract the string # from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by # OPENSTACK_CONFIG_DB_SECTION. import os import sys try: import ConfigParser PARSER_OPTS = {} except ImportError: import configparser as ConfigParser PARSER_OPTS = {"strict": False} import logging from sqlalchemy import create_engine from sqlalchemy import text # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm DB Drop') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the connection string for the service db root user if "ROOT_DB_CONNECTION" in os.environ: db_connection = os.environ['ROOT_DB_CONNECTION'] logger.info('Got DB root connection') else: logger.critical('environment variable ROOT_DB_CONNECTION not set') sys.exit(1) mysql_x509 = os.getenv('MARIADB_X509', "") ssl_args = {} if mysql_x509: ssl_args = {'ssl': {'ca': '/etc/mysql/certs/ca.crt', 'key': '/etc/mysql/certs/tls.key', 'cert': '/etc/mysql/certs/tls.crt'}} # Get the connection string for the service db if "OPENSTACK_CONFIG_FILE" in os.environ: os_conf = os.environ['OPENSTACK_CONFIG_FILE'] if "OPENSTACK_CONFIG_DB_SECTION" in os.environ: os_conf_section = os.environ['OPENSTACK_CONFIG_DB_SECTION'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_SECTION not set') sys.exit(1) if "OPENSTACK_CONFIG_DB_KEY" in os.environ: os_conf_key = os.environ['OPENSTACK_CONFIG_DB_KEY'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_KEY not set') sys.exit(1) try: config = ConfigParser.RawConfigParser(**PARSER_OPTS) logger.info("Using {0} as db config source".format(os_conf)) config.read(os_conf) logger.info("Trying to load db config from {0}:{1}".format( os_conf_section, os_conf_key)) user_db_conn = config.get(os_conf_section, os_conf_key) logger.info("Got config from {0}".format(os_conf)) except: logger.critical("Tried to load config from {0} but failed.".format(os_conf)) raise elif "DB_CONNECTION" in os.environ: user_db_conn = os.environ['DB_CONNECTION'] logger.info('Got config from DB_CONNECTION env var') else: logger.critical('Could not get db config, either from config file or env var') sys.exit(1) # Root DB engine try: root_engine_full = create_engine(db_connection) root_user = root_engine_full.url.username root_password = root_engine_full.url.password drivername = root_engine_full.url.drivername host = root_engine_full.url.host port = root_engine_full.url.port root_engine_url = ''.join([drivername, '://', root_user, ':', root_password, '@', host, ':', str (port)]) root_engine = create_engine(root_engine_url, connect_args=ssl_args) connection = root_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1} as {2}".format( host, port, root_user)) except: logger.critical('Could not connect to database as root user') raise # User DB engine try: user_engine = create_engine(user_db_conn, connect_args=ssl_args) # Get our user data out of the user_engine database = user_engine.url.database user = user_engine.url.username password = user_engine.url.password logger.info('Got user db config') except: logger.critical('Could not get user database config') raise # Delete DB try: with root_engine.connect() as connection: connection.execute(text("DROP DATABASE IF EXISTS {0}".format(database))) try: connection.commit() except AttributeError: pass logger.info("Deleted database {0}".format(database)) except: logger.critical("Could not drop database {0}".format(database)) raise # Delete DB User try: with root_engine.connect() as connection: connection.execute(text("DROP USER IF EXISTS {0}".format(user))) try: connection.commit() except AttributeError: pass logger.info("Deleted user {0}".format(user)) except: logger.critical("Could not delete user {0}".format(user)) raise logger.info('Finished DB Management') db-init.py: ---- #!/usr/bin/env python # Creates db and user for an OpenStack Service: # Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain # SQLAlchemy strings for the root connection to the database and the one you # wish the service to use. Alternatively, you can use an ini formatted config # at the location specified by OPENSTACK_CONFIG_FILE, and extract the string # from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by # OPENSTACK_CONFIG_DB_SECTION. import os import sys try: import ConfigParser PARSER_OPTS = {} except ImportError: import configparser as ConfigParser PARSER_OPTS = {"strict": False} import logging from sqlalchemy import create_engine from sqlalchemy import text # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm DB Init') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the connection string for the service db root user if "ROOT_DB_CONNECTION" in os.environ: db_connection = os.environ['ROOT_DB_CONNECTION'] logger.info('Got DB root connection') else: logger.critical('environment variable ROOT_DB_CONNECTION not set') sys.exit(1) mysql_x509 = os.getenv('MARIADB_X509', "") ssl_args = {} if mysql_x509: ssl_args = {'ssl': {'ca': '/etc/mysql/certs/ca.crt', 'key': '/etc/mysql/certs/tls.key', 'cert': '/etc/mysql/certs/tls.crt'}} # Get the connection string for the service db if "OPENSTACK_CONFIG_FILE" in os.environ: os_conf = os.environ['OPENSTACK_CONFIG_FILE'] if "OPENSTACK_CONFIG_DB_SECTION" in os.environ: os_conf_section = os.environ['OPENSTACK_CONFIG_DB_SECTION'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_SECTION not set') sys.exit(1) if "OPENSTACK_CONFIG_DB_KEY" in os.environ: os_conf_key = os.environ['OPENSTACK_CONFIG_DB_KEY'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_KEY not set') sys.exit(1) try: config = ConfigParser.RawConfigParser(**PARSER_OPTS) logger.info("Using {0} as db config source".format(os_conf)) config.read(os_conf) logger.info("Trying to load db config from {0}:{1}".format( os_conf_section, os_conf_key)) user_db_conn = config.get(os_conf_section, os_conf_key) logger.info("Got config from {0}".format(os_conf)) except: logger.critical("Tried to load config from {0} but failed.".format(os_conf)) raise elif "DB_CONNECTION" in os.environ: user_db_conn = os.environ['DB_CONNECTION'] logger.info('Got config from DB_CONNECTION env var') else: logger.critical('Could not get db config, either from config file or env var') sys.exit(1) # Root DB engine try: root_engine_full = create_engine(db_connection) root_user = root_engine_full.url.username root_password = root_engine_full.url.password drivername = root_engine_full.url.drivername host = root_engine_full.url.host port = root_engine_full.url.port root_engine_url = ''.join([drivername, '://', root_user, ':', root_password, '@', host, ':', str (port)]) root_engine = create_engine(root_engine_url, connect_args=ssl_args) connection = root_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1} as {2}".format( host, port, root_user)) except: logger.critical('Could not connect to database as root user') raise # User DB engine try: user_engine = create_engine(user_db_conn, connect_args=ssl_args) # Get our user data out of the user_engine database = user_engine.url.database user = user_engine.url.username password = user_engine.url.password logger.info('Got user db config') except: logger.critical('Could not get user database config') raise # Create DB try: with root_engine.connect() as connection: connection.execute(text("CREATE DATABASE IF NOT EXISTS {0}".format(database))) try: connection.commit() except AttributeError: pass logger.info("Created database {0}".format(database)) except: logger.critical("Could not create database {0}".format(database)) raise # Create DB User try: with root_engine.connect() as connection: connection.execute( text("CREATE USER IF NOT EXISTS \'{0}\'@\'%\' IDENTIFIED BY \'{1}\' {2}".format( user, password, mysql_x509))) connection.execute( text("GRANT ALL ON `{0}`.* TO \'{1}\'@\'%\'".format(database, user))) try: connection.commit() except AttributeError: pass logger.info("Created user {0} for {1}".format(user, database)) except: logger.critical("Could not create user {0} for {1}".format(user, database)) raise # Test connection try: connection = user_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1}/{2} as {3}".format( host, port, database, user)) except: logger.critical('Could not connect to database as user') raise logger.info('Finished DB Management') ks-endpoints.sh: ---- #!/bin/bash # Copyright 2017 Pete Birley # # 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. set -ex # Get Service ID OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) # Get Endpoint ID if it exists OS_ENDPOINT_ID=$( openstack endpoint list -f csv --quote none | \ grep "^[a-z0-9]*,${OS_REGION_NAME},${OS_SERVICE_NAME},${OS_SERVICE_TYPE},True,${OS_SVC_ENDPOINT}," | \ awk -F ',' '{ print $1 }' ) # Making sure only a single endpoint exists for a service within a region if [ "$(echo $OS_ENDPOINT_ID | wc -w)" -gt "1" ]; then echo "More than one endpoint found, cleaning up" for ENDPOINT_ID in $OS_ENDPOINT_ID; do openstack endpoint delete ${ENDPOINT_ID} done unset OS_ENDPOINT_ID fi # Determine if Endpoint needs updated if [[ ${OS_ENDPOINT_ID} ]]; then OS_ENDPOINT_URL_CURRENT=$(openstack endpoint show ${OS_ENDPOINT_ID} -f value -c url) if [ "${OS_ENDPOINT_URL_CURRENT}" == "${OS_SERVICE_ENDPOINT}" ]; then echo "Endpoints Match: no action required" OS_ENDPOINT_UPDATE="False" else echo "Endpoints Dont Match: removing existing entries" openstack endpoint delete ${OS_ENDPOINT_ID} OS_ENDPOINT_UPDATE="True" fi else OS_ENDPOINT_UPDATE="True" fi # Update Endpoint if required if [[ "${OS_ENDPOINT_UPDATE}" == "True" ]]; then OS_ENDPOINT_ID=$( openstack endpoint create -f value -c id \ --region="${OS_REGION_NAME}" \ "${OS_SERVICE_ID}" \ ${OS_SVC_ENDPOINT} \ "${OS_SERVICE_ENDPOINT}" ) fi # Display the Endpoint openstack endpoint show ${OS_ENDPOINT_ID} BinaryData ==== Events: