Merge "Add LDAP-related actions in application lifecycle"
This commit is contained in:
commit
a98e6464f6
@ -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"
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 $?
|
@ -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
|
||||
|
@ -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[@]} $*
|
@ -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 }}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user