#!/bin/bash # 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. set -xe # The root of the manifest structure to be validated. # This corresponds to the targetPath in an airshipctl config : ${MANIFEST_ROOT:="$(basename "${PWD}")/manifests"} # The location of sites whose manifests should be validated. # This are relative to MANIFEST_ROOT above : ${SITE_ROOT:="$(basename "${PWD}")/manifests/site"} : ${MANIFEST_REPO_URL:="https://review.opendev.org/airship/airshipctl"} : ${SITE:="test-workload"} : ${CONTEXT:="kind-airship"} : ${AIRSHIPKUBECONFIG:="${HOME}/.airship/kubeconfig"} : ${AIRSHIPKUBECONFIG_BACKUP:="${AIRSHIPKUBECONFIG}-backup"} : ${KUBECTL:="/usr/local/bin/kubectl"} TMP=$(mktemp -d) # Use the local project airshipctl binary as the default if it exists, # otherwise use the one on the PATH if [ -f "bin/airshipctl" ]; then AIRSHIPCTL_DEFAULT="bin/airshipctl" else AIRSHIPCTL_DEFAULT="$(which airshipctl)" fi : ${AIRSHIPCONFIG:="${TMP}/config"} : ${AIRSHIPCTL:="${AIRSHIPCTL_DEFAULT}"} ACTL="${AIRSHIPCTL} --airshipconf ${AIRSHIPCONFIG}" export KUBECONFIG="${AIRSHIPKUBECONFIG}" # TODO: use `airshipctl config` to do this once all the needed knobs are exposed # The non-default parts are to set the targetPath appropriately, # and to craft up cluster/contexts to avoid the need for automatic kubectl reconciliation function generate_airshipconf() { cluster=$1 cat <${AIRSHIPCONFIG} apiVersion: airshipit.org/v1alpha1 contexts: ${CONTEXT}_${cluster}: manifest: ${CONTEXT}_${cluster} managementConfiguration: default currentContext: ${CONTEXT}_${cluster} kind: Config managementConfiguration: default: insecure: true systemActionRetries: 30 systemRebootDelay: 30 type: redfish manifests: ${CONTEXT}_${cluster}: phaseRepositoryName: primary repositories: primary: checkout: branch: master commitHash: "" force: false tag: "" url: ${MANIFEST_REPO_URL} targetPath: ${MANIFEST_ROOT} metadataPath: manifests/site/${SITE}/metadata.yaml EOL } function cleanup() { ${KIND} delete cluster --name $CLUSTER rm -rf ${TMP} if [ -f "${AIRSHIPKUBECONFIG_BACKUP}" ]; then echo "Restoring a backup copy of kubeconfig" cp "${AIRSHIPKUBECONFIG_BACKUP}" "${AIRSHIPKUBECONFIG}" fi } trap cleanup EXIT if [ -f "${AIRSHIPKUBECONFIG}" ]; then echo "Making a backup copy of kubeconfig" cp "${AIRSHIPKUBECONFIG}" "${AIRSHIPKUBECONFIG_BACKUP}" fi generate_airshipconf "default" phase_plans=$(airshipctl --airshipconf ${AIRSHIPCONFIG} plan list | grep "PhasePlan" | awk -F '/' '{print $2}' | awk '{print $1}') for plan in $phase_plans; do # Perform static validation first, add support of all plans later if [ "$plan" = "phasePlan" ]; then airshipctl --airshipconf ${AIRSHIPCONFIG} plan validate $plan fi cluster_list=$(airshipctl --airshipconf ${AIRSHIPCONFIG} cluster list) # Loop over all cluster types and phases for the given site for cluster in $cluster_list; do echo -e "\n**** Rendering phases for cluster: ${cluster}" export CLUSTER="${cluster}" # Start a fresh, empty kind cluster for validating documents ./tools/document/start_kind.sh generate_airshipconf ${cluster} # A sequential list of potential phases. A fancier attempt at this has been # removed since it was choking in certain cases and got to be more trouble than was worth. # This should be removed once we have a phase map that is smarter. # In the meantime, as new phases are added, please add them here as well. phases=$(airshipctl --airshipconf ${AIRSHIPCONFIG} phase list --plan $plan -c $cluster | grep Phase | awk -F '/' '{print $2}' | awk '{print $1}' || true) for phase in $phases; do # Guard against bootstrap or initinfra being missing, which could be the case for some configs echo -e "\n*** Rendering ${cluster}/${phase}" # step 1: actually apply all crds in the phase # TODO: will need to loop through phases in order, eventually # e.g., load CRDs from initinfra first, so they're present when validating later phases ${AIRSHIPCTL} --airshipconf ${AIRSHIPCONFIG} phase render ${phase} -s executor -k CustomResourceDefinition >${TMP}/${phase}-crds.yaml if [ -s ${TMP}/${phase}-crds.yaml ]; then ${KUBECTL} --context ${CLUSTER} apply -f ${TMP}/${phase}-crds.yaml fi # step 2: dry-run the entire phase ${ACTL} phase run --dry-run ${phase} done # Delete cluster kubeconfig rm ${KUBECONFIG} ${KIND} delete cluster --name $CLUSTER done done