apiVersion: v1
data:
  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')
  db-sync.sh: |
    #!/bin/bash



    set -ex

    placement-manage db sync
  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}
  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
  placement-api.sh: |
    #!/bin/bash



    set -ex
    COMMAND="${@:-start}"

    function start () {
      exec uwsgi --ini /etc/placement/placement-api-uwsgi.ini
    }

    function stop () {
      kill -TERM 1
    }

    $COMMAND
kind: ConfigMap
metadata:
  annotations:
    meta.helm.sh/release-name: placement
    meta.helm.sh/release-namespace: openstack
  creationTimestamp: "2026-04-22T14:20:08Z"
  labels:
    app.kubernetes.io/managed-by: Helm
  name: placement-bin
  namespace: openstack
  resourceVersion: "12915"
  uid: 20dec69c-2cc6-4228-b4bd-e8904a1089cd
