diff options
Diffstat (limited to 'create-configs.sh')
-rwxr-xr-x | create-configs.sh | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/create-configs.sh b/create-configs.sh new file mode 100755 index 0000000..7d5a591 --- /dev/null +++ b/create-configs.sh @@ -0,0 +1,398 @@ +#!/bin/bash + +# ----------------------------------------------------------------------------- +# Copyright © 2018 AT&T USA +# +# 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. +# +# ----------------------------------------------------------------------------- + +# +# This script generates docker-compose volume overlay files from the oom +# kubernetes configuration files. Multiple environments can be supported. By +# default the environment is the 'local' environment and the docker-compose +# file is named docker-compose-local.yml. This script only generates the +# overlay files, not the docker-compose file. +# +# Overlay files contain the springboot configuration for each SO container. +# +# The idea here is that docker-compose is lighter weight than kubernetes with +# rancher, and people will find it easier to use in a development environment. +# Whenever the overlay files in oom are modified, this script can be used to +# (re)build overlay files for the docker-compose environment. +# +# Reasonably up-to-date overlay files for the docker-compose environment may +# be checked into the docker-config repository as a convenience to those who +# don't want to (or can't) run this script. This script will refresh those. +# +# Example Workflow: +# +# 1) build SO software and docker images -or- pull SO docker images from nexus3 +# +# 2) Create configuration for 'local' environment: +# ./create-configs.sh -e local -i -u rd472p -b master +# +# 3) Start the environment: +# docker-compose -f docker-compose-local.yml up +# + +function usage +{ + echo "usage: $(basename $0) [-e env] [-i] [-u oom-git-user] [-b oom-git-branch]" + echo "where -e specifies the environment name (default: 'local')" + echo " -i re-initializes the staging directory (default: no)" + echo " -u specifies the git user for cloning oom (default: current user)" + echo " -b specifies the oom branch (default: current docker-config branch)" +} + +# +# Purpose: prompts for a yes/no (or equivalent) answer +# Output: none +# Return Code: 0 for yes, 1 for no +# Usage: askConfirm prompt +# +function askConfirm +{ + ask_prompt="$1" + while : + do + echo -n "$ask_prompt" >> /dev/tty + read ask_reply + + ask_reply=${ask_reply##+([[:space:]])}; + ask_reply=${ask_reply%%+([[:space:]])} + + case "$ask_reply" in + y | yes | Y | YES) + return 0 + ;; + n | no | N | NO) + return 1 + ;; + esac + done +} + +# +# Purpose: performs a literal string replacement (no regexs) +# Output: none, but modifies the specified file +# Return Code: 0 for success, 1 for failure +# Usage: replace source replacement file +# +function replace +{ + local src=$1 + local rpl=$2 + local file=$3 + + if ! type xxd > /dev/null 2>&1 + then + echo "xxd: command not found" 1>&2 + return 1 + fi + + local xsrc=$(echo -n "$src" | xxd -p | tr -d '\n') + local xrpl=$(echo -n "$rpl" | xxd -p | tr -d '\n') + + xxd -p $file | tr -d '\n' | sed "s/$xsrc/$xrpl/g" | xxd -p -r > $file.replace || return 1 + mv $file.replace $file || return 1 + return 0 +} + +# +# Purpose: converts a camel-case variable name to snake (upper) case +# openStackUserName -> OPEN_STACK_USER_NAME +# Output: the converted variable name +# Usage: toSnake name +# +function toSnake +{ + echo "$1" | sed -r 's/([A-Z])/_\L\1/g' | sed 's/^_//' | tr '[a-z]' '[A-Z]' +} + +# +# Purpose: lists all the environment variables in the specified docker +# compose yaml for the specified container, e.g.: +# VAR1=VALUE1 +# VAR2=VALUE2 +# ... +# Output: the list of variable mappings +# Usage: listEnv composeFile containerName +# +function listEnv +{ + local composeFile=$1 + local container=$2 + + local inContainer=FALSE + local inEnvironment=FALSE + + while read line + do + if [[ $line == "$container:" ]] + then + inContainer=TRUE + elif [[ $inContainer == TRUE && $line == "environment:" ]] + then + inEnvironment=TRUE + else + if [[ $inEnvironment == TRUE ]] + then + if [[ ${line:0:1} == "-" ]] + then + echo "$line" + else + break + fi + fi + fi + done < $composeFile | sed -e "s/^- '//" -e "s/'$//" +} + +# +# Purpose: tests if the specified environment variable is defined in the +# docker compose yaml for the specified container. +# Output: none +# Return Code: 0 if the variable exists, 1 if it doesn't +# Usage: varExists composeFile containerName variableName +# +function varExists +{ + local composeFile=$1 + local container=$2 + local var=$3 + + listEnv $composeFile $container | grep "^$var=" > /dev/null + return $? +} + +# +# Purpose: returns the value of the specified environment variable +# from the compose yaml for the specified container. +# Output: the variable value (empty if it isn't defined) +# Usage: varValue composeFile containerName variableName +# +function varValue +{ + local composeFile=$1 + local container=$2 + local var=$3 + + listEnv $composeFile $container | grep "^$var=" | cut -d= -f2 +} + +### MAIN CODE STARTS HERE + +if [[ ! -d volumes/so ]] +then + echo "You must run this command in the docker-config directory" 1>&2 + exit 1 +fi + +ENV=local +INIT=FALSE +GITUSER=$(id -un) +GITBRANCH=$(git rev-parse --abbrev-ref HEAD) + +while getopts :e:iu:b: c +do + case "$c" in + e) + ENV=$OPTARG + ;; + i) + INIT=TRUE + ;; + u) + GITUSER=$OPTARG + ;; + b) + GITBRANCH=$OPTARG + ;; + *) + usage 1>&2 + exit 1 + ;; + esac +done + +shift $(($OPTIND - 1)) + +if [[ $# != 0 ]] +then + usage 1>&2 + exit 1 +fi + +if [[ ! -f docker-compose-$ENV.yml ]] +then + echo "No such file: docker-compose-$ENV.yml" 1>&2 + exit 1 +fi + +mkdir -p staging + +if [[ -d staging && $INIT == TRUE ]] +then + if ! askConfirm "Delete existing staging directory? " + then + exit 1 + fi + + rm -fr staging || exit 1 +fi + +mkdir -p staging || exit 1 + +# Get the oom repository from gerrit. + +if [[ -d staging/oom ]] +then + cd staging/oom || exit 1 + + branch=$(git rev-parse --abbrev-ref HEAD) + + if [[ $branch != $GITBRANCH ]] + then + echo "staging/oom is not on branch '$GITBRANCH'" 1>&2 + exit 1 + fi + + cd ../.. || exit 1 +else + cd staging || exit 1 + echo "Cloning into staging/oom" + git clone https://$GITUSER@gerrit.onap.org/r/a/oom || exit 1 + cd oom || exit 1 + + branch=$(git rev-parse --abbrev-ref HEAD) + + if [[ $branch != $GITBRANCH ]] + then + if [[ $(git ls-remote origin $GITBRANCH | wc -l) == 0 ]] + then + echo "staging/oom has no '$GITBRANCH' branch" 1>&2 + exit 1 + fi + + echo "Switching staging/oom to '$GITBRANCH' branch" + git checkout -b $GITBRANCH remotes/origin/$GITBRANCH || exit 1 + fi + + cd ../.. || exit 1 +fi + +kso=staging/oom/kubernetes/so + +if [[ ! -d $kso ]] +then + echo "No such directory: $kso" 1>&2 + exit 1 +fi + +if [[ ! -d staging/volumes/so/config ]] +then + mkdir -p staging/volumes/so/config +fi + +stagedTargets= + +for override in $(cd $kso && find * -name 'override.yaml') +do + subdir=${override%%/*} + + if [[ $subdir == resources ]] + then + container=so-api-handler-infra + elif [[ $subdir == charts ]] + then + container=${override#charts/} + container=${container%%/*} + fi + + if [[ $container != so-monitoring ]] + then + container=${container#so-} + fi + + target=staging/volumes/so/config/$container/$ENV/override.yaml + + if [[ ! -f $target ]] + then + mkdir -p $(dirname $target) || exit 1 + cp $kso/$override $target.tmp || exit 1 + + if ! varExists docker-compose-$ENV.yml $container COMMON_NAMESPACE + then + echo "ERROR: no COMMON_NAMESPACE variable is defined in docker-compose-$ENV.yml for container $container" 1>&2 + exit 1 + fi + + replace '{{ include "common.namespace" . }}' '${COMMON_NAMESPACE}' $target.tmp || exit 1 + + if ! varExists docker-compose-$ENV.yml $container CONTAINER_PORT + then + echo "ERROR: no CONTAINER_PORT variable is defined in docker-compose-$ENV.yml for container $container" 1>&2 + exit 1 + fi + + replace '{{ index .Values.containerPort }}' '${CONTAINER_PORT}' $target.tmp || exit 1 + + for configValue in $(grep "{{ \.Values\.config\..*}}" $target.tmp | cut -d'{' -f3 | cut -d'}' -f1 | tr -d ' ' | sed 's/.Values.config.//' | sort -u) + do + var=$(toSnake $configValue) + + if ! varExists docker-compose-$ENV.yml $container $var + then + echo "ERROR: no $var variable is defined in docker-compose-$ENV.yml for container $container" 1>&2 + exit 1 + fi + + if [[ ${var:0:11} == "OPEN_STACK_" ]] + then + # Workaround for variables in the openstack + # adapter cloud configuration. The override + # yaml is read by a migration program that + # doesn't expand variables, so we need to + # substitute the variable values here. + + value=$(varValue docker-compose-$ENV.yml $container $var) + replace "{{ .Values.config.$configValue }}" "$value" $target.tmp || exit 1 + else + replace "{{ .Values.config.$configValue }}" '${'$var'}' $target.tmp || exit 1 + fi + done + + if grep "{{" $target.tmp > /dev/null + then + echo "ERROR: Unresolved placeholders in $kso/$override:" 1>&2 + grep "{{.*}}" $target.tmp | cut -d'{' -f3 | cut -d'}' -f1 | sed -e 's/^/ {{/' -e 's/$/}}/' | sort -u 1>&2 + exit 1 + fi + + mv $target.tmp $target || exit 1 + echo "Created $target" + + stagedTargets="$stagedTargets target" + fi +done + +for override in $(cd staging && find volumes -name 'override.yaml') +do + dir=$(dirname $override) + mkdir -p $dir || exit 1 + cp staging/$override $override || exit 1 + echo "Installed $override" +done + +echo "SUCCESS" |