#!/bin/bash set -aeou pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" function printHelp(){ cat << EOF Usage ${0##*/} [options..] -h,-?, --help Show help and exit -N, --network-vlan configure network settings -s, --salt run a masterless salt-call -y, --yes answer 'yes' on all questions -i, --image-load pull images so they hits the local proxy -t, --tools Install/update tools (kubectl, helm, etc) -a, --airgap Prepera manifests for airgapped Rancher installs --rmt-sync Sync database with SUSE Customer Center --rmt-enable-products Enable all preconfigured repositories --rmt-mirror Mirror repositories EOF } function asktobreak(){ if [[ "$ANSWER_YES" == true ]];then printf "\n" return 1 fi printf "Do you want to run this step (y/n)" while read -r -n 1 -s answer; do if [[ $answer == [YyNn] ]];then [[ $answer == [Yy] ]] && return_value=1 [[ $answer == [Nn] ]] && return_value=0 printf "\n" break; fi done return $return_value } function new_log(){ # script output printf "\n**** [%s] ***\n" "$*" } function log(){ printf "%s\n" "$*" } function parse_yaml() { # ripped from https://gist.github.com/pkuczynski/8665367#gistcomment-2174214 local yaml_file=$1 local prefix=$2 local s local w local fs s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs="$(echo @|tr @ '\034')" ( sed -ne 's/--//g; s/\"/\\\"/g; s/\#.*//g; s/\s*$//g;' \ -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ -e "s|^\($s\)\($w\)$s[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" | awk -F"$fs" '{ indent = length($1)/2; if (length($2) == 0) { conj[indent]="+";} else {conj[indent]="";} vname[indent] = $2; for (i in vname) {if (i > indent) {delete vname[i]}} if (length($3) > 0) { vn=""; for (i=0; i /dev/null 2>&1 RESULT=$? if [[ $RESULT != 0 ]];then printf "$1 is not installed, do your want to install it [y/N]?" read -r -n 1 -s answer; printf "\n" if [[ $answer == [yY] ]];then sudo zypper --non-interactive install "$1" fi fi set -e } function do_salt_call(){ local salt="sudo salt-call --local --file-root $SCRIPTDIR/salt/states --pillar-root $SCRIPTDIR/salt/pillars --module-dirs=$SCRIPTDIR/salt/modules" new_log "Running salt high state" if asktobreak;then return fi $salt state.apply pillar="{username: $USER}" } function configure_network_vlan(){ new_log "Configure network" if asktobreak; then return fi eval $(parse_yaml salt/pillars/network.sls "SALT_") if [[ -f salt/pillars/local.sls ]];then eval $(parse_yaml salt/pillars/local.sls "SALT_") fi #configure external interface sudo nmcli connection modify "$SALT_network_interface_external" ipv4.method auto sudo nmcli connection up "$SALT_network_interface_external" #configure vlan interfaces local len=${#SALT_network_vlan__id[@]} for (( i=0; i<$len; i++ ));do ifname="vlan.${SALT_network_vlan__id[$i]}" if [[ $(nmcli connection show | grep -i "$ifname" | wc -l) == 0 ]]; then sudo nmcli connection add type vlan con-name "$ifname" ifname "$ifname" dev "$SALT_network_interface_internal" id "${SALT_network_vlan__id[$i]}" fi sudo nmcli connection modify "$ifname" ipv4.addresses "${SALT_network_vlan__address[$i]}/${SALT_network_vlan__netmask[$i]}" sudo nmcli connection modify "$ifname" ipv4.method manual sudo nmcli connection up "$ifname" done } function rmt_sync(){ new_log "Sync RMT Database with SUSE Customer Center" if asktobreak; then return fi sudo rmt-cli sync } function rmt_enable_products(){ new_log "Enable the following products in RMT?" eval $(parse_yaml salt/pillars/rmt.sls "SALT_") if [[ -f salt/pillars/local.sls ]];then eval $(parse_yaml salt/pillars/local.sls "SALT_") fi for name in "${SALT_rmt_products__name[@]}"; do echo " * $name" done if asktobreak; then return fi sudo rmt-cli products enable "${SALT_rmt_products__id[*]}" } function rmt_mirror(){ new_log "Mirror all repositories" if asktobreak; then return fi sudo rmt-cli mirror all } function image_load(){ new_log "Pre Load all Images" for d in "$SCRIPTDIR"/image-lists/*/ ; do name="${d::-1}" name="${name##*/}" for prdir in $SCRIPTDIR/image-lists/$name/*/; do version="${prdir::-1}" version="${version##*/}" echo " * $name $version" done done if asktobreak; then return fi for d in "$SCRIPTDIR"/image-lists/*/ ; do name="${d::-1}" name="${name##*/}" for prdir in $SCRIPTDIR/image-lists/$name/*/; do version="${prdir::-1}" version="${version##*/}" for f in $prdir/*.txt; do echo "Loading $name $version - ${f##*/}" cat $f | while read line do sudo podman image pull "$line" done done done done } function install_tools(){ new_log "Install client tools" echo "- kubectl" echo "- heml" if asktobreak; then return fi set +e echo "---- kubectl ----" cd $HOME/bin if [[ -f kubectl ]]; then KUBECTL_CURRENT=$(./kubectl version 2> /dev/null| sed -n 's/.* GitVersion:"\(v[0-9]*\.[0-9]*\.[0-9]*\)".*/\1/p') else KUBECTL_CURRENT="N/A" fi KUBECTL_STABLE="$(curl -L -s https://dl.k8s.io/release/stable.txt)" echo "Installed version: $KUBECTL_CURRENT" echo "Latest stable version: $KUBECTL_STABLE" if [[ "$KUBECTL_CURRENT" != "$KUBECTL_STABLE" ]]; then curl -LO https://dl.k8s.io/release/$KUBECTL_STABLE/bin/linux/amd64/kubectl chmod +x kubectl fi echo "" echo "---- helm ----" if [[ -f helm ]]; then HELM_CURRENT=$(./helm version | sed -n 's/.*Version:"\(v[0-9]*\.[0-9]*\.[0-9]*\)".*/\1/p') else HELM_CURRENT="N/A" fi HELM_STABLE="$(curl -Ls https://github.com/helm/helm/releases | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | grep -v no-underline | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}')" echo "Installed version: $HELM_CURRENT" echo "Latest stable version: $HELM_STABLE" if [[ "$HELM_CURRENT" != "$HELM_STABLE" ]]; then curl -LO https://get.helm.sh/helm-$HELM_STABLE-linux-amd64.tar.gz tar xvzf helm-$HELM_STABLE-linux-amd64.tar.gz --strip-components=1 linux-amd64/helm rm helm-$HELM_STABLE-linux-amd64.tar.gz fi echo "" set -e } function airgap(){ new_log "Prepair manifests for airgapped installs" for dir in $SCRIPTDIR/image-lists/Rancher/*/; do version="${dir::-1}" version="${version##*/}" echo " * Rancher $version" done if asktobreak; then return fi cd $SCRIPTDIR/airgap helm repo add rancher-latest https://releases.rancher.com/server-charts/latest helm repo add jetstack https://charts.jetstack.io helm repo update #createing manifests for cert-manager helm fetch jetstack/cert-manager --version v1.5.1 if [[ ! -d ./manifests/cert-manager-v1.5.1 ]];then mkdir -p ./manifests/cert-manager-v1.5.1 fi helm template cert-manager ./cert-manager-v1.5.1.tgz --output-dir ./manifests/cert-manager-v1.5.1 \ --namespace cert-manager #--set image.repository=/quay.io/jetstack/cert-manager-controller \ #--set webhook.image.repository=/quay.io/jetstack/cert-manager-webhook \ #--set cainjector.image.repository=/quay.io/jetstack/cert-manager-cainjector curl -L -o ./manifests/cert-manager-v1.5.1/cert-manager-crd.yaml \ https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.crds.yaml #creating manifests for Rancher for dir in $SCRIPTDIR/image-lists/Rancher/*/; do version="${dir::-1}" version="${version##*/}" helm template rancher ./rancher-${version#?}.tgz --output-dir ./manifests/Rancher-$version \ --no-hooks \ --namespace cattle-system \ --set useBundledSystemChart=true # Use the packaged Rancher system charts #--set hostname= \ #--set certmanager.version= \ #--set rancherImage=/rancher/rancher \ #--set systemDefaultRegistry= \ # Set a default private registry to be used in Rancher done } ######################### # # Main Script # ######################## #initialize all options ALL=true SALT=false NETWORK_VLAN=false ANSWER_YES=false RMT_SYNC=false RMT_MIRROR=false RMT_ENABLE_PRODUCTS=false IMAGE_LOAD=false INSTALL_TOOLS=false AIRGAP=false while :; do case ${1-noop} in -h|-\?|--help) printHelp exit ;; -s|--salt) SALT=true ALL=false ;; -N|--network-vlan) NETWORK_VLAN=true ALL=false ;; -y|--yes) ANSWER_YES=true ;; --rmt-sync) RMT_SYNC=true ALL=false ;; --rmt-mirror) RMT_MIRROR=true ALL=false ;; --rmt-enable-products) RMT_ENABLE_PRODUCTS=true ALL=false ;; -i|--image-load) IMAGE_LOAD=true ALL=false ;; -t|--tools) INSTALL_TOOLS=true ALL=false ;; -a|--airgap) AIRGAP=true ALL=false ;; --) #End of all options shift break ;; -?*) printf "'%s' is not a valid option\n" "$1" >&2 exit 1 ;; *) #Break out of case, no more options break esac shift done for cmd in git salt-minion curl;do check_prerequisites "$cmd" done [[ $ALL == true ]] || [[ $NETWORK_VLAN == true ]] && configure_network_vlan [[ $ALL == true ]] || [[ $SALT == true ]] && do_salt_call [[ $ALL == true ]] || [[ $RMT_SYNC == true ]] && rmt_sync [[ $ALL == true ]] || [[ $RMT_ENABLE_PRODUCTS == true ]] && rmt_enable_products [[ $ALL == true ]] || [[ $RMT_MIRROR == true ]] && rmt_mirror [[ $ALL == true ]] || [[ $IMAGE_LOAD == true ]] && image_load [[ $ALL == true ]] || [[ $INSTALL_TOOLS == true ]] && install_tools [[ $ALL == true ]] || [[ $AIRGAP == true ]] && airgap printf "\n DONE!!!!!!!\n"