Container Openstackclient wrapper

With openstackclients moving to a container, issuing openstack
command to the application side would become difficult due to
log "kubectl" commands and the random nature of pod names.

This commit introduces a wrapper for the containerized client
that automatically passes the desired command to the pod.

This commit also introduces a wrapper for copying files dirrectly
to clients container for commands that need filesystem access
(for example creating images with "openstack image create").

We also alias the default openstack command to the containerized
client. The platform openstack command is aliased to
"platform-openstack".

Change-Id: I7b204bb05381d38f4f25066561e001bb8247943b
Signed-off-by: Stefan Dinescu <stefan.dinescu@windriver.com>
Story: 2005312
Task: 30603
Depends-on: I58a5d511cf54dacc018bfb88848899b92a774087
This commit is contained in:
Stefan Dinescu 2019-04-23 11:57:41 +00:00
parent e3778d017e
commit 20ca6a6167
4 changed files with 155 additions and 4 deletions

View File

@ -28,7 +28,8 @@ Platform utilities that don't get packaged on controller hosts
%define local_bindir %{local_dir}/bin
%define local_sbindir %{local_dir}/sbin
%define pythonroot /usr/lib64/python2.7/site-packages
%define local_etc_initd %{_sysconfdir}/init.d
%define system_initd %{_sysconfdir}/init.d
%define system_profiled %{_sysconfdir}/profile.d
%prep
%setup
@ -53,9 +54,11 @@ install -d %{buildroot}%{local_bindir}
install %{_buildsubdir}/scripts/cgcs_tc_setup.sh %{buildroot}%{local_bindir}
install %{_buildsubdir}/scripts/remotelogging_tc_setup.sh %{buildroot}%{local_bindir}
install %{_buildsubdir}/scripts/connectivity_test %{buildroot}%{local_bindir}
install %{_buildsubdir}/scripts/openstack-pod-exec.sh %{buildroot}%{local_bindir}
install %{_buildsubdir}/scripts/openstack-pod-cp.sh %{buildroot}%{local_bindir}
install -d %{buildroot}%{local_etc_initd}
install %{_buildsubdir}/scripts/log_functions.sh %{buildroot}%{local_etc_initd}
install -d %{buildroot}%{system_initd}
install %{_buildsubdir}/scripts/log_functions.sh %{buildroot}%{system_initd}
install -d %{buildroot}%{local_sbindir}
install -m 700 -P -D %{_buildsubdir}/scripts/patch-restart-mtce %{buildroot}%{local_sbindir}
@ -66,6 +69,9 @@ install -d %{buildroot}/etc/systemd/system
install -m 644 -p -D %{_buildsubdir}/scripts/opt-platform.mount %{buildroot}/etc/systemd/system
install -m 644 -p -D %{_buildsubdir}/scripts/opt-platform.service %{buildroot}/etc/systemd/system
install -d %{buildroot}%{system_profiled}
install -m 644 %{_buildsubdir}/scripts/osc-profile.sh %{buildroot}%{system_profiled}
# Mask the systemd ctrl-alt-delete.target, to disable reboot on ctrl-alt-del
ln -sf /dev/null %{buildroot}/etc/systemd/system/ctrl-alt-del.target
@ -83,15 +89,18 @@ systemctl enable opt-platform.service
%{local_bindir}/cgcs_tc_setup.sh
%{local_bindir}/remotelogging_tc_setup.sh
%{local_bindir}/connectivity_test
%{local_bindir}/openstack-pod-exec.sh
%{local_bindir}/openstack-pod-cp.sh
%{local_sbindir}/patch-restart-mtce
%{local_sbindir}/patch-restart-processes
%{local_sbindir}/patch-restart-haproxy
%{system_profiled}/osc-profile.sh
/etc/systemd/system/ctrl-alt-del.target
%dir %{pythonroot}/platform_util
%{pythonroot}/platform_util/*
%dir %{pythonroot}/platform_util-%{version}.0-py2.7.egg-info
%{pythonroot}/platform_util-%{version}.0-py2.7.egg-info/*
%{local_etc_initd}/log_functions.sh
%{system_initd}/log_functions.sh
%files -n platform-util-noncontroller
%defattr(-,root,root,-)

View File

@ -0,0 +1,67 @@
#! /bin/bash
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
CLIENT_IMAGE_NAME="openstack-clients"
NAMESPACE="openstack"
STATE="Running"
MOUNT_PATH="/scratch"
POD_NAME=$(kubectl -n ${NAMESPACE} get pods -o wide 2>&1 |grep ${CLIENT_IMAGE_NAME} |grep ${STATE} |awk '{print $1}')
declare -A levels=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3)
script_log_level="ERROR"
log_message() {
local log_message=$1
local log_message_priority=$2
# check if we provide and invalid log level
if [ -z "${levels[$log_message_priority]}" ]; then
return 1
fi
#check if the log level is above the script log level
if [ ${levels[$log_message_priority]} -lt ${levels[$script_log_level]} ]; then
return 2
fi
echo "${log_message_priority}: ${log_message}"
}
if [ -z "${POD_NAME}" ]; then
log_message "No ${CLIENT_IMAGE_NAME} pod found" "ERROR"
exit 1
fi
if [ "$#" -ne 0 ]; then
param="$1"
if [ "${param}" == "-d" ]; then
MOUNT_PATH="$2"
log_message "Destination override = ${MOUNT_PATH}" "DEBUG"
shift
shift
fi
fi
if [ "$#" -eq 0 ]; then
log_message "Invalid number of parameters" "ERROR"
log_message "Usage: $0 [-d destination] <file_or_directory_path...>" "ERROR"
exit 1
fi
for file_name in "$@"; do
if [[ ! -d "$file_name" && ! -f "$file_name" ]]; then
log_message "Given file \"${file_name}\" not a file or directory" "ERROR"
exit 1
fi
done
for file_name in "$@"; do
log_message "Copying file \"${file_name}\" to pod \"${POD_NAME}\"" "DEBUG"
kubectl cp "${file_name}" "${NAMESPACE}/${POD_NAME}:${MOUNT_PATH}/"
done

View File

@ -0,0 +1,64 @@
#!/bin/bash
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
CLIENT_IMAGE_NAME="openstack-clients"
NAMESPACE="openstack"
STATE="Running"
POD_NAME=$(kubectl -n ${NAMESPACE} get pods -o wide 2>&1 |grep ${CLIENT_IMAGE_NAME} |grep ${STATE} |awk '{print $1}')
declare -A levels=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3)
script_log_level="ERROR"
log_message() {
local log_message=$1
local log_message_priority=$2
# check if we provide and invalid log level
if [ -z "${levels[$log_message_priority]}" ]; then
return 1
fi
#check if the log level is above the script log level
if [ ${levels[$log_message_priority]} -lt ${levels[$script_log_level]} ]; then
return 2
fi
echo "${log_message_priority}: ${log_message}"
}
if [ -z "${POD_NAME}" ]; then
log_message "No openstackclients pod found" "ERROR"
exit 1
fi
log_message "Found clients pod: ${POD_NAME}" "DEBUG"
# Pass stdin to the command only if we use a command that
# is expected to be interactive (like opening an openstack
# shell)
# This script should only be accessed through the defined
# aliases, so the first parameter is always passed.
# Depending on the existence of the second parameter, we
# decide if the command in interactive or not:
# Examples:
# - openstack (translates to ./openstack-pod-exec.sh openstack)
# only has one parameter and is expected to a open an
# interactive openstack shell
# - openstack endpoint list (translates to ./openstack-pod-exec.sh
# openstack endpoint list) is expected to run just one command
# and return the output
# If we had considered all commands as interactive, copying and
# pasting an openstack command followed by any other command
# would have passed all the input after the openstack call as
# input to the pod through "kubectl exec" and not execute the
# commands on the platform side.
if [ -z "$2" ]; then
exec kubectl exec -ti -n ${NAMESPACE} ${POD_NAME} -- "$@"
else
exec kubectl exec -t -n ${NAMESPACE} ${POD_NAME} -- "$@"
fi

View File

@ -0,0 +1,11 @@
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ]; then
alias openstack >/dev/null 2>&1 || alias openstack='/usr/local/bin/openstack-pod-exec.sh openstack'
alias nova >/dev/null 2>&1 || alias nova='/usr/local/bin/openstack-pod-exec.sh nova'
alias platform-openstack >/dev/null 2>&1 || alias platform-openstack=/usr/bin/openstack
fi