diff --git a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/common/constants.py b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/common/constants.py index 0fd09c3f..3ac3287e 100644 --- a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/common/constants.py +++ b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/common/constants.py @@ -107,3 +107,5 @@ CEPH_POOL_VOLUMES_CHUNK_SIZE = 512 CEPH_POOL_BACKUP_APP_NAME = 'cinder-backup' CEPH_POOL_BACKUP_CHUNK_SIZE = 256 + +OPENSTACK_VOLUME_MOUNT_DIR = "/var/opt/openstack" diff --git a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/helpers/__init__.py b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/helpers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/helpers/ldap.py b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/helpers/ldap.py new file mode 100644 index 00000000..b175eaf8 --- /dev/null +++ b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/helpers/ldap.py @@ -0,0 +1,185 @@ +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# All Rights Reserved. +# + +import subprocess +from typing import List + +from oslo_log import log as logging +from sysinv.common import utils as cutils + +LOG = logging.getLogger(__name__) + + +def check_group(group: str) -> bool: + """Check if group exists. + + :returns: bool -- Returns `True` if group exists. + Otherwise, returns `False`. + """ + + # First, run `ldapsearch`. + cmd_p1 = [ + "ldapsearch", + "-x", + "-b", + "ou=Group,dc=cgcs,dc=local", + f"(cn={group})", + ] + p1 = subprocess.Popen( + cmd_p1, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + + # Second, verify if the `ldapsearch` output contains the word `numEntries`. + # If it does, it means that the group exists. + cmd_p2 = ["grep", "numEntries"] + p2 = subprocess.Popen(cmd_p2, stdin=p1.stdout, stdout=subprocess.PIPE) + + p1.stdout.close() + p2.communicate() + + if p2.returncode == 0: + return True + + return False + + +def add_group(group: str) -> None: + """Add group. + + :param group: The group name. + """ + + cmd = ["ldapaddgroup", group] + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning(f"Failed to add group `{group}`: {stderr}") + + +def delete_group(group: str) -> None: + """Delete group. + + :param group: The group name. + """ + + members = list_group_members(group) + for member in members: + delete_group_member(member, group) + + cmd = ["ldapdeletegroup", group] + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning(f"Failed to delete group `{group}`: {stderr}") + + +def check_group_member(member: str, group: str) -> bool: + """Check if group member exists. + + :param member: The member name. + :param group: The group name. + :returns: bool -- Returns `True` if group member exists. + Otherwise, returns `False`. + """ + + # First, run `ldapsearch`. + cmd_p1 = [ + "ldapsearch", + "-x", + "-b", + "ou=Group,dc=cgcs,dc=local", + f"(cn={group})", + ] + p1 = subprocess.Popen( + cmd_p1, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + + # Second, verify if the `ldapsearch` output contains the word `memberUid`. + # If it does, it means that the group not only exists, but also contains + # members. + cmd_p2 = ["grep", f"memberUid: {member}"] + p2 = subprocess.Popen(cmd_p2, stdin=p1.stdout, stdout=subprocess.PIPE) + + p1.stdout.close() + p2.communicate() + + if p2.returncode == 0: + return True + + return False + + +def add_group_member(member: str, group: str) -> None: + """Add group member. + + :param member: The member name. + :param group: The group name. + """ + + cmd = ["ldapaddusertogroup", member, group] + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning( + f"Failed to add user `{member}` to group `{group}`: {stderr}" + ) + + +def delete_group_member(member: str, group: str) -> None: + """Delete group member. + + :param member: The member name. + :param group: The group name. + """ + + cmd = ["ldapdeleteuserfromgroup", member, group] + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning( + f"Failed to delete user `{member}` from group `{group}`: {stderr}" + ) + + +def list_group_members(group: str) -> List[str]: + """List group members. + + :param group: The group name. + :returns: List[str] -- The list of members belonging to + the specified group. + """ + + members = [] + + # First, run `ldapsearch`. + cmd_p1 = [ + "ldapsearch", + "-x", + "-b", + "ou=Group,dc=cgcs,dc=local", + f"(cn={group})", + ] + p1 = subprocess.Popen( + cmd_p1, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + + # Second, verify if the `ldapsearch` output contains the word `memberUid`. + # If it does, it means that the group not only exists, but also contains + # members. + cmd_p2 = ["grep", "-Poh", "(?<=memberUid: )(.*)"] + p2 = subprocess.Popen(cmd_p2, stdin=p1.stdout, stdout=subprocess.PIPE) + + p1.stdout.close() + stdout, _ = p2.communicate() + + if p2.returncode == 0: + for user in stdout.decode().split(): + if user: + members.append(user) + + return members diff --git a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/lifecycle/lifecycle_openstack.py b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/lifecycle/lifecycle_openstack.py index 994e1726..20b0b386 100644 --- a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/lifecycle/lifecycle_openstack.py +++ b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/lifecycle/lifecycle_openstack.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2021 Wind River Systems, Inc. +# Copyright (c) 2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -18,6 +18,8 @@ from sysinv.helm import lifecycle_utils as lifecycle_utils from sysinv.helm.lifecycle_constants import LifecycleConstants from k8sapp_openstack import utils as app_utils +from k8sapp_openstack.common import constants as app_constants +from k8sapp_openstack.helpers import ldap LOG = logging.getLogger(__name__) @@ -97,6 +99,8 @@ class OpenstackAppLifecycleOperator(base.AppLifecycleOperator): """ hook_info[LifecycleConstants.EXTRA][self.WAS_APPLIED] = app.active + self._pre_apply_ldap_actions() + def post_apply(self, context, conductor_obj, app, hook_info): """ Post apply actions @@ -156,6 +160,8 @@ class OpenstackAppLifecycleOperator(base.AppLifecycleOperator): conductor_obj._update_vim_config(context) conductor_obj._update_radosgw_config(context) + self._post_remove_ldap_actions() + def _delete_app_specific_resources_post_remove(self, app_op, app, hook_info): """Delete application specific resources. @@ -291,3 +297,26 @@ class OpenstackAppLifecycleOperator(base.AppLifecycleOperator): not installed. Otherwise, False. """ return app_utils.https_enabled() and not app_utils.is_openstack_https_certificates_ready() + + def _pre_apply_ldap_actions(self): + """Perform pre apply LDAP-related actions.""" + + # Create `openstack` group. + has_group = ldap.check_group(app_constants.HELM_NS_OPENSTACK) + if not has_group: + ldap.add_group(app_constants.HELM_NS_OPENSTACK) + + # Create the volume mount directory. + app_utils.create_openstack_volume_mount() + + def _post_remove_ldap_actions(self): + """Perform post remove LDAP-related actions.""" + + # Try to delete the volume mount directory. + # If successful, delete `openstack` group. + # Otherwise, do nothing. + deleted = app_utils.delete_openstack_volume_mount() + if deleted: + has_group = ldap.check_group(app_constants.HELM_NS_OPENSTACK) + if has_group: + ldap.delete_group(app_constants.HELM_NS_OPENSTACK) diff --git a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/utils.py b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/utils.py index 8f65d43c..7c1d1b9b 100644 --- a/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/utils.py +++ b/python3-k8sapp-openstack/k8sapp_openstack/k8sapp_openstack/utils.py @@ -1,12 +1,21 @@ # -# Copyright (c) 2022 Wind River Systems, Inc. +# Copyright (c) 2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # +from pathlib import Path +import shutil + +from oslo_log import log as logging from sysinv.common import constants +from sysinv.common import utils as cutils from sysinv.db import api as dbapi +from k8sapp_openstack.common import constants as app_constants + +LOG = logging.getLogger(__name__) + def https_enabled(): db = dbapi.get_instance() @@ -47,3 +56,156 @@ def is_openstack_https_ready(): installed in the system. """ return https_enabled() and is_openstack_https_certificates_ready() + + +def change_file_group_ownership( + file: str, + group: str, + recursive: bool = False +) -> None: + """Change file's group ownership. + + :param file: The file path. + :param group: The group name. + :param recursive: bool -- The flag that indicates whether permissions + should be changed recursively or not. + """ + + cmd = ["chgrp", group, file] + + if recursive: + cmd.insert(1, "-R") + + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning( + f"Failed to change group ownership of `{file}` " + f"to `{group}`: {stderr}" + ) + + +def change_file_owner( + file: str, + user: str = "", + group: str = "", + recursive: bool = False +) -> None: + """Change file's owner (chown). + + :param file: The file path. + :param user: The desired user. + :param group: The desired group. + :param recursive: bool -- The flag that indicates whether ownerships + should be changed recursively or not. + """ + + ownership = "" + + if user: + ownership += user + + if group: + ownership += f":{group}" + + if not ownership: + return + + cmd = ["chown", ownership, file] + + if recursive: + cmd.insert(1, "-R") + + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning( + f"Failed to change ownership of `{file}` " + f"to `{ownership}`: {stderr}" + ) + + +def change_file_mode( + file: str, + mode: str, + recursive: bool = False +) -> None: + """Change file's mode (chmod). + + + :param file: The file path. + :param mode: The desired mode. + :param recursive: bool -- The flag that indicates whether modes should be + changed recursively or not. + """ + + cmd = ["chmod", mode, file] + + if recursive: + cmd.insert(1, "-R") + + _, stderr = cutils.trycmd(*cmd, run_as_root=True) + + if stderr: + LOG.warning( + f"Failed to change mode of `{file}` to `{mode}`: {stderr}" + ) + + +def create_openstack_volume_mount() -> None: + """Create OpenStack volume mount directory.""" + + p = Path(app_constants.OPENSTACK_VOLUME_MOUNT_DIR) + p.mkdir(exist_ok=True) + + # Change modes of the volume mount directory. + change_file_mode( + str(p), + mode="770", + recursive=True + ) + + # Change ownership of the volume mount directory. + change_file_owner( + str(p), + user="sysadmin", + group=app_constants.HELM_NS_OPENSTACK, + recursive=True + ) + + +def delete_openstack_volume_mount() -> bool: + """Delete OpenStack volume mount. + + :returns: bool -- True, if volume mount directory was successfully deleted. + False, if otherwise. + """ + + # Search for additional files that might have been created by users. + directories = [app_constants.OPENSTACK_VOLUME_MOUNT_DIR] + while directories: + p = Path(directories.pop(0)) + for pathname in p.glob("*"): + if pathname.is_dir(): + directories.append(str(pathname)) + continue + else: + # Ignore files in the root directory. + if str(p) == app_constants.OPENSTACK_VOLUME_MOUNT_DIR: + continue + + # If there is at least one file created by users outside the + # root directory, that is, in a user subdirectory, it means + # that we can't remove the volume mount directory. + LOG.warning( + f"Unable to delete OpenStack volume mount directory " + f"`{app_constants.OPENSTACK_VOLUME_MOUNT_DIR}`. " + f"There are one or more user files in subdirectories." + ) + return False + + shutil.rmtree( + app_constants.OPENSTACK_VOLUME_MOUNT_DIR, ignore_errors=True + ) + + return True diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clear-aliases.sh.tpl b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clear-aliases.sh.tpl index e93eeb48..6e45da86 100644 --- a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clear-aliases.sh.tpl +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clear-aliases.sh.tpl @@ -1,19 +1,20 @@ #!/bin/bash +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Clears OpenStack service aliases. +# -{{/* -Copyright (c) 2023 Wind River Systems, Inc. - -SPDX-License-Identifier: Apache-2.0 -*/}} - -SERVICES=" - openstack - nova +SERVICES=( cinder glance heat -" + nova + openstack +) -for service in ${SERVICES}; do +for service in "${SERVICES[@]}"; do unalias "${service}" 2> /dev/null done diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-init.sh.tpl b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-init.sh.tpl index 6d3432d4..a319985c 100644 --- a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-init.sh.tpl +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-init.sh.tpl @@ -1,21 +1,68 @@ #!/bin/bash - -{{/* -Copyright (c) 2023 Wind River Systems, Inc. - -SPDX-License-Identifier: Apache-2.0 -*/}} +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Copies setup scripts to the volume mount directory and creates an openrc +# file for admin access to the OpenStack clients container. +# set -ex +TMP_DIR=/tmp OPENSTACK_DIR=/var/opt/openstack -OPENSTACK_SCRIPTS=( - /tmp/clear-aliases.sh - /tmp/setup-aliases.sh - /tmp/wrapper.sh +OPENSTACK_SETUP_SCRIPTS=( + clear-aliases.sh + setup-aliases.sh + clients-wrapper.sh + local_openstackrc ) -mkdir -p ${OPENSTACK_DIR}/sysadmin -cp ${OPENSTACK_SCRIPTS[@]} ${OPENSTACK_DIR} -chmod -R 755 ${OPENSTACK_DIR} +# Store ownership of the volume mount directory to use it later on other files. +ownership=$(ls -nd "${OPENSTACK_DIR}" | awk '{print $3":"$4}') + +# Copy setup scripts to volume mount directory and adjust their mode/ownership +# to make them only usable by their corresponding owners and/or groups. +for setup_script in "${OPENSTACK_SETUP_SCRIPTS[@]}"; do + + cp "${TMP_DIR}/${setup_script}" "${OPENSTACK_DIR}" + chmod 550 "${OPENSTACK_DIR}/${setup_script}" + chown "${ownership}" "${OPENSTACK_DIR}/${setup_script}" + +done + +# Create openrc file for admin access. +ADMIN_OPENRC="${OPENSTACK_DIR}/admin-openrc" + +touch "${ADMIN_OPENRC}" +chmod 600 "${ADMIN_OPENRC}" +chown "${ownership}" "${ADMIN_OPENRC}" + +cat << EOF >> "${ADMIN_OPENRC}" +source /etc/platform/openrc --no_credentials + +if [[ "$?" -ne 0 ]]; then + return 1 +fi + +source "${OPENSTACK_DIR}/setup-aliases.sh" + +if [[ "$?" -ne 0 ]]; then + return 1 +fi + +export OS_USERNAME={{ .Values.endpoints.identity.auth.admin.username }} +export OS_PASSWORD={{ .Values.endpoints.identity.auth.admin.password }} + +export OS_AUTH_URL=\ +{{ .Values.endpoints.identity.scheme.default }}://\ +{{ .Values.endpoints.identity.name }}.openstack.svc.\ +{{ .Values.endpoints.cluster_domain_suffix }}\ +{{ .Values.endpoints.identity.path.default }} + +export PS1='[\u@\h \W(keystone_\$OS_USERNAME)]\$ ' + +return 0 +EOF diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-wrapper.sh.tpl b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-wrapper.sh.tpl new file mode 100644 index 00000000..c7ed1487 --- /dev/null +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_clients-wrapper.sh.tpl @@ -0,0 +1,69 @@ +#!/bin/bash -i +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# OpenStack clients wrapper responsible for executing commands +# passed as arguments in a containerized environment. +# + +OPENSTACK_DIR=/var/opt/openstack + +OPENSTACK_VARIABLES=( + OS_AUTH_TYPE + OS_AUTH_URL + OS_CACERT + OS_IDENTITY_API_SERVICE + OS_INTERFACE + OS_PASSWORD + OS_PROJECT_DOMAIN_ID + OS_PROJECT_DOMAIN_NAME + OS_PROJECT_ID + OS_PROJECT_NAME + OS_REGION_NAME + OS_USERNAME + OS_USER_DOMAIN_NAME +) + +if [[ -z "${KUBECONFIG}" ]]; then + KUBECONFIG=/etc/kubernetes/admin.conf +fi + +ENV_ARGUMENTS=() +for variable in "${OPENSTACK_VARIABLES[@]}"; do + if [[ ! -z "$(printenv ${variable})" ]]; then + ENV_ARGUMENTS+=("${variable}=$(printenv ${variable})") + fi +done + +CONTROLLER=$(echo "${PS1@P}" | grep -Po 'controller-\d+' | cut -d $'\n' -f 1) +if [[ -z "${CONTROLLER}" ]]; then + echo "OpenStack CLIs can only be accessed from a controller node." + exit 1 +fi + +POD=$( + kubectl --kubeconfig "${KUBECONFIG}" -n openstack get pods \ + | grep -i "clients-${CONTROLLER}.*Running" | awk '{print $1}' +) +if [[ -z "${POD}" ]]; then + echo "Could not find \`clients\` pod in ${CONTROLLER}." + echo "Make sure the pod is running and try again." + exit 1 +fi + +if grep -q "^${USER}:" /etc/passwd; then + kubectl --kubeconfig "${KUBECONFIG}" -n openstack exec -it "${POD}" \ + -c clients -- env ${ENV_ARGUMENTS[@]} /bin/bash -c "$*" +else + if [[ ! -d "${OPENSTACK_DIR}/${USER}" ]]; then + mkdir -p "${OPENSTACK_DIR}/${USER}" + chgrp -R openstack "${OPENSTACK_DIR}/${USER}" + fi + + kubectl --kubeconfig "${KUBECONFIG}" -n openstack exec -it "${POD}" \ + -c clients -- env ${ENV_ARGUMENTS[@]} /bin/bash -c "cd ${USER}; $*" +fi + + diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_local_openstackrc.tpl b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_local_openstackrc.tpl new file mode 100644 index 00000000..b1f04441 --- /dev/null +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_local_openstackrc.tpl @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Creates and/or loads local file "~/$USER-openrc-openstack". +# +# Assumes the Keystone username is the same as the logged in username. +# + +OPENSTACK_DIR=/var/opt/openstack +OPENSTACK_OPENRC=${HOME}/${USER}-openrc-openstack + +# Check if local openrc file exists. +if [[ -e "${OPENSTACK_OPENRC}" ]]; then + + # If it does, source it. + source "${OPENSTACK_OPENRC}" + return $? + +fi + +# Otherwise, create and source it. +read -s -p "Enter password for Keystone user \`${USER}\`: " password + +touch "${OPENSTACK_OPENRC}" +chmod 600 "${OPENSTACK_OPENRC}" + +cat << EOF >> "${OPENSTACK_OPENRC}" +source /etc/platform/openrc --no_credentials + +if [[ "$?" -ne 0 ]]; then + return 1 +fi + +source "${OPENSTACK_DIR}/setup-aliases.sh" + +if [[ "$?" -ne 0 ]]; then + return 1 +fi + +export OS_USERNAME="${USER}" +export OS_PASSWORD="${password}" + +export OS_AUTH_URL=\ +{{ .Values.endpoints.identity.scheme.default }}://\ +{{ .Values.endpoints.identity.name }}.openstack.svc.\ +{{ .Values.endpoints.cluster_domain_suffix }}\ +{{ .Values.endpoints.identity.path.default }} + +export PS1='[\u@\h \W(keystone_\$OS_USERNAME)]\$ ' + +return 0 +EOF + +echo +echo "Created file \`${OPENSTACK_OPENRC}\`." +source "${OPENSTACK_OPENRC}" +return $? diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_setup-aliases.sh.tpl b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_setup-aliases.sh.tpl index c3d76651..a0df28e8 100644 --- a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_setup-aliases.sh.tpl +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_setup-aliases.sh.tpl @@ -1,25 +1,29 @@ #!/bin/bash - -{{/* -Copyright (c) 2023 Wind River Systems, Inc. - -SPDX-License-Identifier: Apache-2.0 -*/}} +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Creates OpenStack service aliases. +# +# All aliases created redirect OpenStack commands to a wrapper script, +# which executes them in a containerized environment. +# if [[ ${BASH_SOURCE} = '/'* ]]; then - PATH_TO_SCRIPT=$(dirname ${BASH_SOURCE}) + PATH_TO_SCRIPT=$(dirname "${BASH_SOURCE}") else - PATH_TO_SCRIPT=$(pwd)/$(dirname ${BASH_SOURCE}) + PATH_TO_SCRIPT=$(pwd)/$(dirname "${BASH_SOURCE}") fi -SERVICES=" - openstack - nova +SERVICES=( cinder glance heat -" + nova + openstack +) -for service in ${SERVICES}; do - alias "${service}"="${PATH_TO_SCRIPT}/wrapper.sh ${service}" +for service in "${SERVICES[@]}"; do + alias "${service}"="${PATH_TO_SCRIPT}/clients-wrapper.sh ${service}" done diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_wrapper.sh.tpl b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_wrapper.sh.tpl deleted file mode 100644 index 04390bcc..00000000 --- a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/bin/_wrapper.sh.tpl +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -i - -{{/* -Copyright (c) 2023 Wind River Systems, Inc. - -SPDX-License-Identifier: Apache-2.0 -*/}} - -OPENSTACK_VARIABLES=" - OS_AUTH_TYPE - OS_AUTH_URL - OS_CACERT - OS_IDENTITY_API_SERVICE - OS_INTERFACE - OS_PASSWORD - OS_PROJECT_DOMAIN_ID - OS_PROJECT_DOMAIN_NAME - OS_PROJECT_ID - OS_PROJECT_NAME - OS_REGION_NAME - OS_USERNAME - OS_USER_DOMAIN_NAME -" - -ENV_ARGUMENTS=() -for variable in ${OPENSTACK_VARIABLES}; do - if [[ ! -z "$(printenv ${variable})" ]]; then - ENV_ARGUMENTS+=("${variable}=$(printenv ${variable})") - fi -done - -CONTROLLER=$(echo ${PS1@P} | grep -Po 'controller-\d+') -if [[ -z "${CONTROLLER}" ]]; then - echo "OpenStack CLIs can only be accessed from a controller node." - exit 1 -fi - -POD=$(kubectl -n openstack get pods | grep -i "clients-${CONTROLLER}.*Running" | awk '{print $1}') -if [[ -z "${POD}" ]]; then - echo "Could not find \`clients\` pod in ${CONTROLLER}." - echo "Make sure the pod is running and try again." - exit 1 -fi - -kubectl -n openstack exec -it ${POD} -c clients -- env ${ENV_ARGUMENTS[@]} $* diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/configmap-bin.yaml b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/configmap-bin.yaml index 867d5cfa..010098bb 100644 --- a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/configmap-bin.yaml +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/configmap-bin.yaml @@ -17,12 +17,14 @@ metadata: data: clients-init.sh: | {{ tuple "bin/_clients-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + clients-wrapper.sh: | +{{ tuple "bin/_clients-wrapper.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} clear-aliases.sh: | {{ tuple "bin/_clear-aliases.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} setup-aliases.sh: | {{ tuple "bin/_setup-aliases.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} - wrapper.sh: | -{{ tuple "bin/_wrapper.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + local_openstackrc: | +{{ tuple "bin/_local_openstackrc.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- end }} diff --git a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/daemonset-clients.yaml b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/daemonset-clients.yaml index d31098d2..be10e046 100644 --- a/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/daemonset-clients.yaml +++ b/stx-openstack-helm-fluxcd/stx-openstack-helm-fluxcd/helm-charts/clients/templates/daemonset-clients.yaml @@ -53,6 +53,10 @@ spec: mountPath: /tmp/clients-init.sh subPath: clients-init.sh readOnly: true + - name: clients-bin + mountPath: /tmp/clients-wrapper.sh + subPath: clients-wrapper.sh + readOnly: true - name: clients-bin mountPath: /tmp/clear-aliases.sh subPath: clear-aliases.sh @@ -62,8 +66,8 @@ spec: subPath: setup-aliases.sh readOnly: true - name: clients-bin - mountPath: /tmp/wrapper.sh - subPath: wrapper.sh + mountPath: /tmp/local_openstackrc + subPath: local_openstackrc readOnly: true - name: host-var-opt mountPath: /var/opt