From e17e10dd1389b6c09ff7674d0c800d4b277a21ef Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Tue, 4 Oct 2022 17:17:10 +1100 Subject: [PATCH 01/17] chore: use build-deploy-tool for backup generation --- legacy/build-deploy-docker-compose.sh | 5 +- legacy/scripts/exec-backup-generation.sh | 330 ----------------------- 2 files changed, 4 insertions(+), 331 deletions(-) delete mode 100755 legacy/scripts/exec-backup-generation.sh diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index 251423b8..2c647bff 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -1037,7 +1037,10 @@ set -x # Run the backup generation script -. /kubectl-build-deploy/scripts/exec-backup-generation.sh +# build-tool doesn't do any capability checks yet, so do this for now +if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then + build-deploy-tool template backup-schedule +fi # check for ISOLATION_NETWORK_POLICY feature flag, disabled by default set +x diff --git a/legacy/scripts/exec-backup-generation.sh b/legacy/scripts/exec-backup-generation.sh deleted file mode 100755 index c4ebfe49..00000000 --- a/legacy/scripts/exec-backup-generation.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash - -set +x -############################################## -# it is possible to override the retention using a variable defined in the api -# -# if you want to use a different retention period for production branches, you can use the following -# LAGOON_BACKUP_PROD_RETENTION="H:D:W:M" - -# if you want to use a different retention period for development branches, you can use the following -# LAGOON_BACKUP_DEV_RETENTION="H:D:W:M" -# -# if you want to use a different retention period for pullrequest environments, you can use the following -# LAGOON_BACKUP_PR_RETENTION="H:D:W:M" -# -# Where the value H:D:W:M (hourly:daily:weekly:monthly) is numbers representing the retention period -# eg: 0:7:6:1 -# 0 Hourly -# 7 Daily -# 6 Weekly -# 1 Montly -# -############################################## - -# Implement global default value for backup retentions -if [ -z "$MONTHLY_BACKUP_DEFAULT_RETENTION" ] -then - MONTHLY_BACKUP_DEFAULT_RETENTION=1 -fi -if [ -z "$WEEKLY_BACKUP_DEFAULT_RETENTION" ] -then - WEEKLY_BACKUP_DEFAULT_RETENTION=6 -fi -if [ -z "$DAILY_BACKUP_DEFAULT_RETENTION" ] -then - DAILY_BACKUP_DEFAULT_RETENTION=7 -fi -if [ -z "$HOURLY_BACKUP_DEFAULT_RETENTION" ] -then - HOURLY_BACKUP_DEFAULT_RETENTION=0 -fi - -############################################## -# it is possible to override the schedule using a variable defined in the api -# -# if you want to use a different schedule period for development branches, you can use the following -# LAGOON_BACKUP_DEV_SCHEDULE="M H(22-2) * * *" -# -# if you want to use a different retention period for pullrequest environments, you can use the following -# LAGOON_BACKUP_PR_SCHEDULE="M H(22-2) * * *" -# -# Where the value is a supported cronjob pattern for k8up -############################################## - - -############################################## -### Backup Settings -############################################## - -# If k8up is supported by this cluster we create the schedule definition -if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then - - # Parse out custom baas backup location variables - if [ ! -z "$LAGOON_PROJECT_VARIABLES" ]; then - BAAS_CUSTOM_BACKUP_ENDPOINT=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_BACKUP_ENDPOINT") | "\(.value)"')) - BAAS_CUSTOM_BACKUP_BUCKET=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_BACKUP_BUCKET") | "\(.value)"')) - BAAS_CUSTOM_BACKUP_ACCESS_KEY=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_BACKUP_ACCESS_KEY") | "\(.value)"')) - BAAS_CUSTOM_BACKUP_SECRET_KEY=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_BACKUP_SECRET_KEY") | "\(.value)"')) - - if [ ! -z $BAAS_CUSTOM_BACKUP_ENDPOINT ] && [ ! -z $BAAS_CUSTOM_BACKUP_BUCKET ] && [ ! -z $BAAS_CUSTOM_BACKUP_ACCESS_KEY ] && [ ! -z $BAAS_CUSTOM_BACKUP_SECRET_KEY ]; then - CUSTOM_BAAS_BACKUP_ENABLED=1 - - HELM_CUSTOM_BAAS_BACKUP_ACCESS_KEY=${BAAS_CUSTOM_BACKUP_ACCESS_KEY} - HELM_CUSTOM_BAAS_BACKUP_SECRET_KEY=${BAAS_CUSTOM_BACKUP_SECRET_KEY} - else - kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete secret baas-custom-backup-credentials --ignore-not-found - fi - fi - - # Parse out custom baas restore location variables - if [ ! -z "$LAGOON_PROJECT_VARIABLES" ]; then - BAAS_CUSTOM_RESTORE_ENDPOINT=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_RESTORE_ENDPOINT") | "\(.value)"')) - BAAS_CUSTOM_RESTORE_BUCKET=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_RESTORE_BUCKET") | "\(.value)"')) - BAAS_CUSTOM_RESTORE_ACCESS_KEY=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_RESTORE_ACCESS_KEY") | "\(.value)"')) - BAAS_CUSTOM_RESTORE_SECRET_KEY=($(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_CUSTOM_RESTORE_SECRET_KEY") | "\(.value)"')) - - if [ ! -z $BAAS_CUSTOM_RESTORE_ENDPOINT ] && [ ! -z $BAAS_CUSTOM_RESTORE_BUCKET ] && [ ! -z $BAAS_CUSTOM_RESTORE_ACCESS_KEY ] && [ ! -z $BAAS_CUSTOM_RESTORE_SECRET_KEY ]; then - HELM_CUSTOM_BAAS_RESTORE_ACCESS_KEY=${BAAS_CUSTOM_RESTORE_ACCESS_KEY} - HELM_CUSTOM_BAAS_RESTORE_SECRET_KEY=${BAAS_CUSTOM_RESTORE_SECRET_KEY} - else - kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete secret baas-custom-restore-credentials --ignore-not-found - fi - fi - - if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then - # Create baas-repo-pw secret based on the project secret - kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "$PROJECT_SECRET-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) - fi - - TEMPLATE_PARAMETERS=() - - # Check for custom baas bucket name - if [ ! -z "$LAGOON_PROJECT_VARIABLES" ]; then - BAAS_BUCKET_NAME=$(echo $LAGOON_PROJECT_VARIABLES | jq -r '.[] | select(.name == "LAGOON_BAAS_BUCKET_NAME") | "\(.value)"') - fi - if [ -z $BAAS_BUCKET_NAME ]; then - BAAS_BUCKET_NAME=baas-${PROJECT} - fi - - # Pull in .lagoon.yml variables - PRODUCTION_MONTHLY_BACKUP_RETENTION=$(cat .lagoon.yml | shyaml get-value backup-retention.production.monthly "") - PRODUCTION_WEEKLY_BACKUP_RETENTION=$(cat .lagoon.yml | shyaml get-value backup-retention.production.weekly "") - PRODUCTION_DAILY_BACKUP_RETENTION=$(cat .lagoon.yml | shyaml get-value backup-retention.production.daily "") - PRODUCTION_HOURLY_BACKUP_RETENTION=$(cat .lagoon.yml | shyaml get-value backup-retention.production.hourly "") - - # Set template parameters for retention values (prefer .lagoon.yml values over supplied defaults after ensuring they are valid integers via "-eq" comparison) - if [[ ! -z $PRODUCTION_MONTHLY_BACKUP_RETENTION ]] && [[ "$PRODUCTION_MONTHLY_BACKUP_RETENTION" -eq "$PRODUCTION_MONTHLY_BACKUP_RETENTION" ]] && [[ $ENVIRONMENT_TYPE = 'production' ]]; then - MONTHLY_BACKUP_DEFAULT_RETENTION=${PRODUCTION_MONTHLY_BACKUP_RETENTION} - else - MONTHLY_BACKUP_RETENTION=${MONTHLY_BACKUP_DEFAULT_RETENTION} - fi - if [[ ! -z $PRODUCTION_WEEKLY_BACKUP_RETENTION ]] && [[ "$PRODUCTION_WEEKLY_BACKUP_RETENTION" -eq "$PRODUCTION_WEEKLY_BACKUP_RETENTION" ]] && [[ $ENVIRONMENT_TYPE = 'production' ]]; then - WEEKLY_BACKUP_DEFAULT_RETENTION=${PRODUCTION_WEEKLY_BACKUP_RETENTION} - else - WEEKLY_BACKUP_RETENTION=${WEEKLY_BACKUP_DEFAULT_RETENTION} - fi - if [[ ! -z $PRODUCTION_DAILY_BACKUP_RETENTION ]] && [[ "$PRODUCTION_DAILY_BACKUP_RETENTION" -eq "$PRODUCTION_DAILY_BACKUP_RETENTION" ]] && [[ $ENVIRONMENT_TYPE = 'production' ]]; then - DAILY_BACKUP_DEFAULT_RETENTION=${PRODUCTION_DAILY_BACKUP_RETENTION} - else - DAILY_BACKUP_RETENTION=${DAILY_BACKUP_DEFAULT_RETENTION} - fi - if [[ ! -z $PRODUCTION_HOURLY_BACKUP_RETENTION ]] && [[ "$PRODUCTION_HOURLY_BACKUP_RETENTION" -eq "$PRODUCTION_HOURLY_BACKUP_RETENTION" ]] && [[ $ENVIRONMENT_TYPE = 'production' ]]; then - HOURLY_BACKUP_DEFAULT_RETENTION=${PRODUCTION_HOURLY_BACKUP_RETENTION} - else - HOURLY_BACKUP_RETENTION=${HOURLY_BACKUP_DEFAULT_RETENTION} - fi - - ############################################## - # check if the feature for custom backup configuration is enabled LAGOON_FEATURE_FLAG(_FORCE|_DEFAULT)_CUSTOM_BACKUP_CONFIG=enabled - # this feature is experimental and may cause issues with your backups if incorrectly used, talk to your lagoon administrators before you use this - # _ - # __| | __ _ _ __ __ _ ___ _ __ - # / _` |/ _` | '_ \ / _` |/ _ \ '__| - # | (_| | (_| | | | | (_| | __/ | - # \__,_|\__,_|_| |_|\__, |\___|_| - # |___/ - ############################################## - - if [ "$(featureFlag CUSTOM_BACKUP_CONFIG)" = enabled ]; then - # check if a specific override has been defined in the api - case "$BUILD_TYPE" in - promote) - if [ "${ENVIRONMENT_TYPE}" == "production" ]; then - # check if the API defined variable LAGOON_BACKUP_PROD_RETENTION contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_BACKUP_PROD_RETENTION - BACKUP_RETENTION=$(projectEnvironmentVariableCheck LAGOON_BACKUP_PROD_RETENTION "${LAGOON_FEATURE_BACKUP_PROD_RETENTION}") - if [ ! -z "$BACKUP_RETENTION" ]; then - IFS=':' read -ra BACKUP_RETENTION_SPLIT <<< "$BACKUP_RETENTION" - HOURLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[0]} - DAILY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[1]} - WEEKLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[2]} - MONTHLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[3]} - fi - fi - ;; - branch) - if [ "${ENVIRONMENT_TYPE}" == "production" ]; then - # check if the API defined variable LAGOON_BACKUP_PROD_RETENTION contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_BACKUP_PROD_RETENTION - BACKUP_RETENTION=$(projectEnvironmentVariableCheck LAGOON_BACKUP_PROD_RETENTION "${LAGOON_FEATURE_BACKUP_PROD_RETENTION}") - if [ ! -z "$BACKUP_RETENTION" ]; then - IFS=':' read -ra BACKUP_RETENTION_SPLIT <<< "$BACKUP_RETENTION" - HOURLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[0]} - DAILY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[1]} - WEEKLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[2]} - MONTHLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[3]} - fi - fi - if [ "${ENVIRONMENT_TYPE}" == "development" ]; then - # check if the API defined variable LAGOON_BACKUP_DEV_RETENTION contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_DEV_RETENTION - BACKUP_RETENTION=$(projectEnvironmentVariableCheck LAGOON_BACKUP_DEV_RETENTION "${LAGOON_FEATURE_BACKUP_DEV_RETENTION}") - if [ ! -z "$BACKUP_RETENTION" ]; then - IFS=':' read -ra BACKUP_RETENTION_SPLIT <<< "$BACKUP_RETENTION" - HOURLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[0]} - DAILY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[1]} - WEEKLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[2]} - MONTHLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[3]} - fi - fi - ;; - pullrequest) - # check if the API defined variable LAGOON_BACKUP_PR_RETENTION contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_PR_RETENTION - BACKUP_RETENTION=$(projectEnvironmentVariableCheck LAGOON_BACKUP_PR_RETENTION "${LAGOON_FEATURE_BACKUP_PR_RETENTION}") - if [ ! -z "$BACKUP_RETENTION" ]; then - IFS=':' read -ra BACKUP_RETENTION_SPLIT <<< "$BACKUP_RETENTION" - HOURLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[0]} - DAILY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[1]} - WEEKLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[2]} - MONTHLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[3]} - fi - if [ -z "$BACKUP_RETENTION" ];then - ## fall back to dev retention if no pr retention is defined - # check if the API defined variable LAGOON_BACKUP_DEV_RETENTION contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_DEV_RETENTION - BACKUP_RETENTION=$(projectEnvironmentVariableCheck LAGOON_BACKUP_DEV_RETENTION "${LAGOON_FEATURE_BACKUP_DEV_RETENTION}") - if [ ! -z "$BACKUP_RETENTION" ]; then - IFS=':' read -ra BACKUP_RETENTION_SPLIT <<< "$BACKUP_RETENTION" - HOURLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[0]} - DAILY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[1]} - WEEKLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[2]} - MONTHLY_BACKUP_DEFAULT_RETENTION=${BACKUP_RETENTION_SPLIT[3]} - fi - fi - ;; - *) - echo "${BUILD_TYPE} not implemented"; exit 1; - esac - fi - - MONTHLY_BACKUP_RETENTION=${MONTHLY_BACKUP_DEFAULT_RETENTION} - WEEKLY_BACKUP_RETENTION=${WEEKLY_BACKUP_DEFAULT_RETENTION} - DAILY_BACKUP_RETENTION=${DAILY_BACKUP_DEFAULT_RETENTION} - HOURLY_BACKUP_RETENTION=${HOURLY_BACKUP_DEFAULT_RETENTION} - - # Set template parameters for backup schedule value (prefer .lagoon.yml values over supplied defaults after ensuring they are valid) - PRODUCTION_BACKUP_SCHEDULE=$(cat .lagoon.yml | shyaml get-value backup-schedule.production "") - - if [[ ! -z $PRODUCTION_BACKUP_SCHEDULE ]] && [[ $ENVIRONMENT_TYPE = 'production' ]]; then - if [[ "$PRODUCTION_BACKUP_SCHEDULE" =~ ^M\ ]]; then - DEFAULT_BACKUP_SCHEDULE=${PRODUCTION_BACKUP_SCHEDULE} - else - echo "Error parsing custom backup schedule: '$PRODUCTION_BACKUP_SCHEDULE'"; exit 1 - fi - fi - - if [ "$(featureFlag CUSTOM_BACKUP_CONFIG)" = enabled ]; then - # check if a specific override has been defined in the api - case "$BUILD_TYPE" in - promote) - if [ "${ENVIRONMENT_TYPE}" == "production" ]; then - # check if the API defined variable LAGOON_BACKUP_PROD_SCHEDULE contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_DEV_SCHEDULE - DEFAULT_BACKUP_SCHEDULE=$(projectEnvironmentVariableCheck LAGOON_BACKUP_PROD_SCHEDULE "${LAGOON_FEATURE_BACKUP_PROD_SCHEDULE}") - fi - ;; - branch) - if [ "${ENVIRONMENT_TYPE}" == "production" ]; then - # check if the API defined variable LAGOON_BACKUP_PROD_SCHEDULE contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_DEV_SCHEDULE - DEFAULT_BACKUP_SCHEDULE=$(projectEnvironmentVariableCheck LAGOON_BACKUP_PROD_SCHEDULE "${LAGOON_FEATURE_BACKUP_PROD_SCHEDULE}") - fi - if [ "${ENVIRONMENT_TYPE}" == "development" ]; then - # check if the API defined variable LAGOON_BACKUP_DEV_SCHEDULE contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_DEV_SCHEDULE - DEFAULT_BACKUP_SCHEDULE=$(projectEnvironmentVariableCheck LAGOON_BACKUP_DEV_SCHEDULE "${LAGOON_FEATURE_BACKUP_DEV_SCHEDULE}") - fi - ;; - pullrequest) - # check if the API defined variable LAGOON_BACKUP_PR_SCHEDULE contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_PR_SCHEDULE - DEFAULT_BACKUP_SCHEDULE=$(projectEnvironmentVariableCheck LAGOON_BACKUP_PR_SCHEDULE "${LAGOON_FEATURE_BACKUP_PR_SCHEDULE}") - if [ -z "$DEFAULT_BACKUP_SCHEDULE" ];then - ## fall back to dev schedule if no pr schedule is defined - # check if the API defined variable LAGOON_BACKUP_DEV_SCHEDULE contains what is needed - # if one in the API is not defined, fall back to what could be injected by the controller LAGOON_FEATURE_BACKUP_DEV_SCHEDULE - DEFAULT_BACKUP_SCHEDULE=$(projectEnvironmentVariableCheck LAGOON_BACKUP_DEV_SCHEDULE "${LAGOON_FEATURE_BACKUP_DEV_SCHEDULE}") - fi - ;; - *) - echo "${BUILD_TYPE} not implemented"; exit 1; - esac - fi - - # Implement global default value for backup schedule - if [ -z "$DEFAULT_BACKUP_SCHEDULE" ] - then - DEFAULT_BACKUP_SCHEDULE="M H(22-2) * * *" - fi - - BACKUP_SCHEDULE=$( /kubectl-build-deploy/scripts/convert-crontab.sh "${NAMESPACE}" "${DEFAULT_BACKUP_SCHEDULE}") - - if [ ! -z $K8UP_WEEKLY_RANDOM_FEATURE_FLAG ] && [ $K8UP_WEEKLY_RANDOM_FEATURE_FLAG = 'enabled' ]; then - # Let the controller deduplicate checks (will run weekly at a random time throughout the week) - CHECK_SCHEDULE="@weekly-random" - else - # Run Checks on Sunday at 0300-0600 - CHECK_SCHEDULE=$( /kubectl-build-deploy/scripts/convert-crontab.sh "${NAMESPACE}" "M H(3-6) * * 0") - fi - - if [ ! -z $K8UP_WEEKLY_RANDOM_FEATURE_FLAG ] && [ $K8UP_WEEKLY_RANDOM_FEATURE_FLAG = 'enabled' ]; then - # Let the controller deduplicate prunes (will run weekly at a random time throughout the week) - PRUNE_SCHEDULE="@weekly-random" - else - # Run Prune on Saturday at 0300-0600 - PRUNE_SCHEDULE=$( /kubectl-build-deploy/scripts/convert-crontab.sh "${NAMESPACE}" "M H(3-6) * * 6") - fi - - # Set the S3 variables which should be passed to the helm chart - if [ ! -z $CUSTOM_BAAS_BACKUP_ENABLED ]; then - BAAS_BACKUP_ENDPOINT=${BAAS_CUSTOM_BACKUP_ENDPOINT} - BAAS_BACKUP_BUCKET=${BAAS_CUSTOM_BACKUP_BUCKET} - BAAS_BACKUP_SECRET_NAME='lagoon-baas-custom-backup-credentials' - else - BAAS_BACKUP_ENDPOINT='' - BAAS_BACKUP_BUCKET=${BAAS_BUCKET_NAME} - BAAS_BACKUP_SECRET_NAME='' - fi - - OPENSHIFT_TEMPLATE="/kubectl-build-deploy/openshift-templates/backup-schedule.yml" - helm template k8up-lagoon-backup-schedule /kubectl-build-deploy/helmcharts/k8up-schedule \ - -f /kubectl-build-deploy/values.yaml \ - --set backup.schedule="${BACKUP_SCHEDULE}" \ - --set check.schedule="${CHECK_SCHEDULE}" \ - --set prune.schedule="${PRUNE_SCHEDULE}" \ - --set prune.retention.keepMonthly=${MONTHLY_BACKUP_RETENTION} \ - --set prune.retention.keepWeekly=${WEEKLY_BACKUP_RETENTION} \ - --set prune.retention.keepDaily=${DAILY_BACKUP_RETENTION} \ - --set prune.retention.keepHourly=${HOURLY_BACKUP_RETENTION} \ - --set s3.endpoint="${BAAS_BACKUP_ENDPOINT}" \ - --set s3.bucket="${BAAS_BACKUP_BUCKET}" \ - --set s3.secretName="${BAAS_BACKUP_SECRET_NAME}" \ - --set customRestoreLocation.accessKey="${BAAS_CUSTOM_RESTORE_ACCESS_KEY}" \ - --set customRestoreLocation.secretKey="${BAAS_CUSTOM_RESTORE_SECRET_KEY}" \ - --set customBackupLocation.accessKey="${BAAS_CUSTOM_BACKUP_ACCESS_KEY}" \ - --set customBackupLocation.secretKey="${BAAS_CUSTOM_BACKUP_SECRET_KEY}" "${HELM_ARGUMENTS[@]}" > $YAML_FOLDER/k8up-lagoon-backup-schedule.yaml -fi - -set -x \ No newline at end of file From 54716a4a30d2a9c28b1ee53e96a875e496513d23 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Tue, 4 Oct 2022 17:21:43 +1100 Subject: [PATCH 02/17] fix: use the same file name the script used --- cmd/template_backups.go | 2 +- .../{backups.yaml => k8up-lagoon-backup-schedule.yaml} | 0 .../{backups.yaml => k8up-lagoon-backup-schedule.yaml} | 0 .../{backups.yaml => k8up-lagoon-backup-schedule.yaml} | 0 .../{backups.yaml => k8up-lagoon-backup-schedule.yaml} | 0 .../{backups.yaml => k8up-lagoon-backup-schedule.yaml} | 0 .../{backups.yaml => k8up-lagoon-backup-schedule.yaml} | 0 7 files changed, 1 insertion(+), 1 deletion(-) rename test-resources/template-backups/test1-results/{backups.yaml => k8up-lagoon-backup-schedule.yaml} (100%) rename test-resources/template-backups/test2-results/{backups.yaml => k8up-lagoon-backup-schedule.yaml} (100%) rename test-resources/template-backups/test3-results/{backups.yaml => k8up-lagoon-backup-schedule.yaml} (100%) rename test-resources/template-backups/test4-results/{backups.yaml => k8up-lagoon-backup-schedule.yaml} (100%) rename test-resources/template-backups/test5-results/{backups.yaml => k8up-lagoon-backup-schedule.yaml} (100%) rename test-resources/template-backups/test6-results/{backups.yaml => k8up-lagoon-backup-schedule.yaml} (100%) diff --git a/cmd/template_backups.go b/cmd/template_backups.go index 609096d6..17b96d29 100644 --- a/cmd/template_backups.go +++ b/cmd/template_backups.go @@ -37,7 +37,7 @@ func BackupTemplateGeneration(g generator.GeneratorInput, if err != nil { return fmt.Errorf("couldn't generate template: %v", err) } - helpers.WriteTemplateFile(fmt.Sprintf("%s/%s.yaml", savedTemplates, "backups"), templateYAML) + helpers.WriteTemplateFile(fmt.Sprintf("%s/%s.yaml", savedTemplates, "k8up-lagoon-backup-schedule"), templateYAML) return nil } diff --git a/test-resources/template-backups/test1-results/backups.yaml b/test-resources/template-backups/test1-results/k8up-lagoon-backup-schedule.yaml similarity index 100% rename from test-resources/template-backups/test1-results/backups.yaml rename to test-resources/template-backups/test1-results/k8up-lagoon-backup-schedule.yaml diff --git a/test-resources/template-backups/test2-results/backups.yaml b/test-resources/template-backups/test2-results/k8up-lagoon-backup-schedule.yaml similarity index 100% rename from test-resources/template-backups/test2-results/backups.yaml rename to test-resources/template-backups/test2-results/k8up-lagoon-backup-schedule.yaml diff --git a/test-resources/template-backups/test3-results/backups.yaml b/test-resources/template-backups/test3-results/k8up-lagoon-backup-schedule.yaml similarity index 100% rename from test-resources/template-backups/test3-results/backups.yaml rename to test-resources/template-backups/test3-results/k8up-lagoon-backup-schedule.yaml diff --git a/test-resources/template-backups/test4-results/backups.yaml b/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml similarity index 100% rename from test-resources/template-backups/test4-results/backups.yaml rename to test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml diff --git a/test-resources/template-backups/test5-results/backups.yaml b/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml similarity index 100% rename from test-resources/template-backups/test5-results/backups.yaml rename to test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml diff --git a/test-resources/template-backups/test6-results/backups.yaml b/test-resources/template-backups/test6-results/k8up-lagoon-backup-schedule.yaml similarity index 100% rename from test-resources/template-backups/test6-results/backups.yaml rename to test-resources/template-backups/test6-results/k8up-lagoon-backup-schedule.yaml From d438d3f17d6651d3cc0538e866a6528efb337a08 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Tue, 4 Oct 2022 17:22:04 +1100 Subject: [PATCH 03/17] chore: remove the old helmchart for k8up-schedule --- legacy/helmcharts/k8up-schedule/.helmignore | 22 ------ legacy/helmcharts/k8up-schedule/Chart.yaml | 17 ----- .../k8up-schedule/templates/_helpers.tpl | 68 ------------------- .../custom-baas-backup-location-secret.yaml | 13 ---- .../custom-baas-restore-location-secret.yaml | 13 ---- .../k8up-schedule/templates/schedule.yaml | 39 ----------- legacy/helmcharts/k8up-schedule/values.yaml | 24 ------- 7 files changed, 196 deletions(-) delete mode 100644 legacy/helmcharts/k8up-schedule/.helmignore delete mode 100644 legacy/helmcharts/k8up-schedule/Chart.yaml delete mode 100644 legacy/helmcharts/k8up-schedule/templates/_helpers.tpl delete mode 100644 legacy/helmcharts/k8up-schedule/templates/custom-baas-backup-location-secret.yaml delete mode 100644 legacy/helmcharts/k8up-schedule/templates/custom-baas-restore-location-secret.yaml delete mode 100644 legacy/helmcharts/k8up-schedule/templates/schedule.yaml delete mode 100644 legacy/helmcharts/k8up-schedule/values.yaml diff --git a/legacy/helmcharts/k8up-schedule/.helmignore b/legacy/helmcharts/k8up-schedule/.helmignore deleted file mode 100644 index 50af0317..00000000 --- a/legacy/helmcharts/k8up-schedule/.helmignore +++ /dev/null @@ -1,22 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/legacy/helmcharts/k8up-schedule/Chart.yaml b/legacy/helmcharts/k8up-schedule/Chart.yaml deleted file mode 100644 index 6ca616e8..00000000 --- a/legacy/helmcharts/k8up-schedule/Chart.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v2 -name: k8up-schedule -description: A Helm chart for Kubernetes creating k8up backup schedule - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -version: 0.2.0 \ No newline at end of file diff --git a/legacy/helmcharts/k8up-schedule/templates/_helpers.tpl b/legacy/helmcharts/k8up-schedule/templates/_helpers.tpl deleted file mode 100644 index 2274ee2c..00000000 --- a/legacy/helmcharts/k8up-schedule/templates/_helpers.tpl +++ /dev/null @@ -1,68 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "k8up-schedule.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "k8up-schedule.fullname" -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "k8up-schedule.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Common labels -*/}} -{{- define "k8up-schedule.labels" -}} -helm.sh/chart: {{ include "k8up-schedule.chart" . }} -{{ include "k8up-schedule.selectorLabels" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{ include "k8up-schedule.lagoonLabels" . }} - -{{- end -}} - -{{/* -Selector labels -*/}} -{{- define "k8up-schedule.selectorLabels" -}} -app.kubernetes.io/name: {{ include "k8up-schedule.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end -}} - -{{/* -Lagoon Labels -*/}} -{{- define "k8up-schedule.lagoonLabels" -}} -lagoon.sh/service: {{ .Release.Name }} -lagoon.sh/service-type: {{ .Chart.Name }} -lagoon.sh/project: {{ .Values.project }} -lagoon.sh/environment: {{ .Values.environment }} -lagoon.sh/environmentType: {{ .Values.environmentType }} -lagoon.sh/buildType: {{ .Values.buildType }} -{{- end -}} - -{{/* -Annotations -*/}} -{{- define "k8up-schedule.annotations" -}} -lagoon.sh/version: {{ .Values.lagoonVersion | quote }} -{{- if .Values.branch }} -lagoon.sh/branch: {{ .Values.branch | quote }} -{{- end }} -{{- if .Values.prNumber }} -lagoon.sh/prNumber: {{ .Values.prNumber | quote }} -lagoon.sh/prHeadBranch: {{ .Values.prHeadBranch | quote }} -lagoon.sh/prBaseBranch: {{ .Values.prBaseBranch | quote }} -{{- end }} -{{- end -}} \ No newline at end of file diff --git a/legacy/helmcharts/k8up-schedule/templates/custom-baas-backup-location-secret.yaml b/legacy/helmcharts/k8up-schedule/templates/custom-baas-backup-location-secret.yaml deleted file mode 100644 index 1d012f5d..00000000 --- a/legacy/helmcharts/k8up-schedule/templates/custom-baas-backup-location-secret.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and (.Values.customBackupLocation.accessKey) (.Values.customBackupLocation.secretKey) }} -apiVersion: v1 -kind: Secret -metadata: - name: lagoon-baas-custom-backup-credentials - labels: - {{- include "k8up-schedule.labels" . | nindent 4 }} - annotations: - {{- include "k8up-schedule.annotations" . | nindent 4 }} -stringData: - access-key: {{ .Values.customBackupLocation.accessKey }} - secret-key: {{ .Values.customBackupLocation.secretKey }} -{{ end }} \ No newline at end of file diff --git a/legacy/helmcharts/k8up-schedule/templates/custom-baas-restore-location-secret.yaml b/legacy/helmcharts/k8up-schedule/templates/custom-baas-restore-location-secret.yaml deleted file mode 100644 index 7b1b6bec..00000000 --- a/legacy/helmcharts/k8up-schedule/templates/custom-baas-restore-location-secret.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and (.Values.customRestoreLocation.accessKey) (.Values.customRestoreLocation.secretKey) }} -apiVersion: v1 -kind: Secret -metadata: - name: lagoon-baas-custom-restore-credentials - labels: - {{- include "k8up-schedule.labels" . | nindent 4 }} - annotations: - {{- include "k8up-schedule.annotations" . | nindent 4 }} -stringData: - access-key: {{ .Values.customRestoreLocation.accessKey }} - secret-key: {{ .Values.customRestoreLocation.secretKey }} -{{ end }} \ No newline at end of file diff --git a/legacy/helmcharts/k8up-schedule/templates/schedule.yaml b/legacy/helmcharts/k8up-schedule/templates/schedule.yaml deleted file mode 100644 index 8ee52295..00000000 --- a/legacy/helmcharts/k8up-schedule/templates/schedule.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: backup.appuio.ch/v1alpha1 -kind: Schedule -metadata: - name: {{ include "k8up-schedule.fullname" . }} - labels: - {{- include "k8up-schedule.labels" . | nindent 4 }} - annotations: - {{- include "k8up-schedule.annotations" . | nindent 4 }} -spec: - backend: - repoPasswordSecretRef: - key: repo-pw - name: baas-repo-pw - s3: - {{- if .Values.s3.endpoint }} - endpoint: '{{ .Values.s3.endpoint }}' - {{- end }} - {{- if .Values.s3.bucket }} - bucket: '{{ .Values.s3.bucket }}' - {{- end }} - {{- if .Values.s3.secretName }} - accessKeyIDSecretRef: - name: '{{ .Values.s3.secretName }}' - key: access-key - secretAccessKeySecretRef: - name: '{{ .Values.s3.secretName }}' - key: secret-key - {{- end }} - backup: - schedule: '{{ .Values.backup.schedule }}' - check: - schedule: '{{ .Values.check.schedule }}' - prune: - retention: - keepHourly: {{ .Values.prune.retention.keepHourly }} - keepDaily: {{ .Values.prune.retention.keepDaily }} - keepWeekly: {{ .Values.prune.retention.keepWeekly }} - keepMonthly: {{ .Values.prune.retention.keepMonthly }} - schedule: '{{ .Values.prune.schedule }}' diff --git a/legacy/helmcharts/k8up-schedule/values.yaml b/legacy/helmcharts/k8up-schedule/values.yaml deleted file mode 100644 index e054b951..00000000 --- a/legacy/helmcharts/k8up-schedule/values.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Default values for k8up-schedule. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -safeProject: project - -backup: - schedule: '0 * * * *' - -check: - schedule: '0 * * * 0' - -prune: - retention: - keepHourly: 0 - keepDaily: 7 - keepWeekly: 6 - keepMonthly: 1 - schedule: '0 * * * 6' - -s3: - endpoint: '' - bucket: '' - secretName: '' \ No newline at end of file From 375ed681e596fe59ca4dc291a67c0d422eacf0ca Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Wed, 5 Oct 2022 13:31:49 +1100 Subject: [PATCH 04/17] chore: add baas-repo-pw secret creation --- legacy/build-deploy-docker-compose.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index 2c647bff..6958ee96 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -1039,6 +1039,10 @@ set -x # Run the backup generation script # build-tool doesn't do any capability checks yet, so do this for now if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then + if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then + # Create baas-repo-pw secret based on the project secret + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) + fi build-deploy-tool template backup-schedule fi From f115b7495e928d0c18979a1570ce7a6326f6e23e Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Wed, 5 Oct 2022 14:01:12 +1100 Subject: [PATCH 05/17] fix: actually put a bucket name in :) --- cmd/template_backups_test.go | 6 +- internal/generator/backups.go | 96 +++++++++++++------ internal/generator/backups_test.go | 61 ++++++++++-- .../backups/template_schedule_test.go | 1 + .../test-resources/result-schedule2.yaml | 3 +- .../k8up-lagoon-backup-schedule.yaml | 3 +- .../k8up-lagoon-backup-schedule.yaml | 3 +- .../k8up-lagoon-backup-schedule.yaml | 3 +- .../k8up-lagoon-backup-schedule.yaml | 1 + .../k8up-lagoon-backup-schedule.yaml | 3 +- .../k8up-lagoon-backup-schedule.yaml | 3 +- 11 files changed, 141 insertions(+), 42 deletions(-) diff --git a/cmd/template_backups_test.go b/cmd/template_backups_test.go index fd1a47b9..998d9df7 100644 --- a/cmd/template_backups_test.go +++ b/cmd/template_backups_test.go @@ -72,7 +72,7 @@ func TestBackupTemplateGeneration(t *testing.T) { buildType: "branch", lagoonVersion: "v2.7.x", branch: "main", - projectVars: `[{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, + projectVars: `[{"name":"LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG","value":"enabled","scope":"global"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test2/lagoon.yml", templatePath: "../test-resources/template-backups/output", @@ -111,7 +111,7 @@ func TestBackupTemplateGeneration(t *testing.T) { prBaseBranch: "main2", lagoonVersion: "v2.7.x", branch: "main", - projectVars: `[{"name":"LAGOON_BAAS_CUSTOM_BACKUP_ACCESS_KEY","value":"abcdefg","scope":"build"},{"name":"LAGOON_BAAS_CUSTOM_BACKUP_SECRET_KEY","value":"abcdefg1234567","scope":"build"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_BACKUP_PR_SCHEDULE","value":"3,33 12 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, + projectVars: `[{"name":"LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG","value":"enabled","scope":"global"},{"name":"LAGOON_BAAS_CUSTOM_BACKUP_ACCESS_KEY","value":"abcdefg","scope":"build"},{"name":"LAGOON_BAAS_CUSTOM_BACKUP_SECRET_KEY","value":"abcdefg1234567","scope":"build"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_BACKUP_PR_SCHEDULE","value":"3,33 12 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test4/lagoon.yml", templatePath: "../test-resources/template-backups/output", @@ -132,7 +132,7 @@ func TestBackupTemplateGeneration(t *testing.T) { prBaseBranch: "main2", lagoonVersion: "v2.7.x", branch: "main", - projectVars: `[{"name":"LAGOON_BAAS_CUSTOM_RESTORE_ACCESS_KEY","value":"abcdefg","scope":"build"},{"name":"LAGOON_BAAS_CUSTOM_RESTORE_SECRET_KEY","value":"abcdefg1234567","scope":"build"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_BACKUP_PR_SCHEDULE","value":"3,33 12 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, + projectVars: `[{"name":"LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG","value":"enabled","scope":"global"},{"name":"LAGOON_BAAS_CUSTOM_RESTORE_ACCESS_KEY","value":"abcdefg","scope":"build"},{"name":"LAGOON_BAAS_CUSTOM_RESTORE_SECRET_KEY","value":"abcdefg1234567","scope":"build"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_BACKUP_PR_SCHEDULE","value":"3,33 12 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test5/lagoon.yml", templatePath: "../test-resources/template-backups/output", diff --git a/internal/generator/backups.go b/internal/generator/backups.go index ef1dc38c..9542564a 100644 --- a/internal/generator/backups.go +++ b/internal/generator/backups.go @@ -15,6 +15,9 @@ const ( dailyDefaultBackupRetention = 7 weeklyDefaultBackupRetention = 6 monthlyDefaultBackupRetention = 1 + + // TODO: make this configurable + baasBucketPrefix = "baas" ) func generateBackupValues( @@ -28,39 +31,69 @@ func generateBackupValues( // create a new schedule placeholder set to the default value so it can be adjusted through this // generator newBackupSchedule := defaultBackupSchedule - switch buildValues.BuildType { - case "branch": - if buildValues.EnvironmentType == "development" { - lagoonBackupDevSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_DEV_SCHEDULE", []string{"build", "global"}, mergedVariables) - devBackupSchedule := "" - if lagoonBackupDevSchedule != nil { - devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", lagoonBackupDevSchedule.Value, debug) - } else { - devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", newBackupSchedule, debug) + + customBackupConfig := CheckFeatureFlag("CUSTOM_BACKUP_CONFIG", mergedVariables, debug) + if customBackupConfig == "enabled" { + switch buildValues.BuildType { + case "promote": + if buildValues.EnvironmentType == "production" { + lagoonBackupDevSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_PROD_SCHEDULE", []string{"build", "global"}, mergedVariables) + devBackupSchedule := "" + if lagoonBackupDevSchedule != nil { + devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PROD_SCHEDULE", lagoonBackupDevSchedule.Value, debug) + } else { + devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PROD_SCHEDULE", newBackupSchedule, debug) + } + if devBackupSchedule != "" { + newBackupSchedule = devBackupSchedule + } } - if devBackupSchedule != "" { - newBackupSchedule = devBackupSchedule + case "branch": + if buildValues.EnvironmentType == "production" { + lagoonBackupDevSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_PROD_SCHEDULE", []string{"build", "global"}, mergedVariables) + devBackupSchedule := "" + if lagoonBackupDevSchedule != nil { + devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PROD_SCHEDULE", lagoonBackupDevSchedule.Value, debug) + } else { + devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PROD_SCHEDULE", newBackupSchedule, debug) + } + if devBackupSchedule != "" { + newBackupSchedule = devBackupSchedule + } } - } - case "pullrequest": - lagoonBackupPRSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_PR_SCHEDULE", []string{"build", "global"}, mergedVariables) - prBackupSchedule := "" - if lagoonBackupPRSchedule != nil { - prBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PR_SCHEDULE", lagoonBackupPRSchedule.Value, debug) - } else { - prBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PR_SCHEDULE", prBackupSchedule, debug) - } - if prBackupSchedule == "" { - lagoonBackupDevSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_DEV_SCHEDULE", []string{"build", "global"}, mergedVariables) - if lagoonBackupDevSchedule != nil { - newBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", lagoonBackupDevSchedule.Value, debug) + if buildValues.EnvironmentType == "development" { + lagoonBackupDevSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_DEV_SCHEDULE", []string{"build", "global"}, mergedVariables) + devBackupSchedule := "" + if lagoonBackupDevSchedule != nil { + devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", lagoonBackupDevSchedule.Value, debug) + } else { + devBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", newBackupSchedule, debug) + } + if devBackupSchedule != "" { + newBackupSchedule = devBackupSchedule + } + } + case "pullrequest": + lagoonBackupPRSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_PR_SCHEDULE", []string{"build", "global"}, mergedVariables) + prBackupSchedule := "" + if lagoonBackupPRSchedule != nil { + prBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PR_SCHEDULE", lagoonBackupPRSchedule.Value, debug) } else { - newBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", newBackupSchedule, debug) + prBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_PR_SCHEDULE", prBackupSchedule, debug) + } + if prBackupSchedule == "" { + lagoonBackupDevSchedule, _ := lagoon.GetLagoonVariable("LAGOON_BACKUP_DEV_SCHEDULE", []string{"build", "global"}, mergedVariables) + if lagoonBackupDevSchedule != nil { + newBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", lagoonBackupDevSchedule.Value, debug) + } else { + newBackupSchedule = helpers.GetEnv("LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", newBackupSchedule, debug) + } + } else { + newBackupSchedule = prBackupSchedule } - } else { - newBackupSchedule = prBackupSchedule } } + buildValues.Backup.BackupSchedule, err = helpers.ConvertCrontab(buildValues.Namespace, newBackupSchedule) if err != nil { return fmt.Errorf("Unable to convert crontab for default backup schedule: %v", err) @@ -122,6 +155,15 @@ func generateBackupValues( return fmt.Errorf("Unable to convert crontab for default backup schedule from .lagoon.yml: %v", err) } } + + // work out the bucket name + lagoonBaaSBackupBucket, _ := lagoon.GetLagoonVariable("LAGOON_BAAS_BUCKET_NAME", []string{"build", "global"}, mergedVariables) + if lagoonBaaSBackupBucket != nil { + buildValues.Backup.S3BucketName = lagoonBaaSBackupBucket.Value + } else { + buildValues.Backup.S3BucketName = fmt.Sprintf("%s-%s", baasBucketPrefix, buildValues.Project) + } + // check for custom baas backup variables in the API lagoonBaaSCustomBackupEndpoint, _ := lagoon.GetLagoonVariable("LAGOON_BAAS_CUSTOM_BACKUP_ENDPOINT", []string{"build", "global"}, mergedVariables) if lagoonBaaSCustomBackupEndpoint != nil { diff --git a/internal/generator/backups_test.go b/internal/generator/backups_test.go index 9d316b4f..36ebf211 100644 --- a/internal/generator/backups_test.go +++ b/internal/generator/backups_test.go @@ -30,6 +30,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -38,11 +39,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "31 1 * * *", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -58,21 +61,25 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, mergedVariables: []lagoon.EnvironmentVariable{ + {Name: "LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG", Value: "enabled", Scope: "global"}, {Name: "LAGOON_BACKUP_DEV_SCHEDULE", Value: "M/15 23 * * 0-5", Scope: "build"}, }, }, want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 23 * * 0-5", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -88,10 +95,13 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, - lYAML: &lagoon.YAML{}, - mergedVariables: []lagoon.EnvironmentVariable{}, + lYAML: &lagoon.YAML{}, + mergedVariables: []lagoon.EnvironmentVariable{ + {Name: "LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG", Value: "enabled", Scope: "global"}, + }, }, vars: []helpers.EnvironmentVariable{ {Name: "LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", Value: "1,16,31,46 23 * * 0-5"}, @@ -99,11 +109,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 23 * * 0-5", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -119,21 +131,25 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, mergedVariables: []lagoon.EnvironmentVariable{ + {Name: "LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG", Value: "enabled", Scope: "global"}, {Name: "LAGOON_BACKUP_PR_SCHEDULE", Value: "M/15 23 * * 0-5", Scope: "build"}, }, }, want: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 23 * * 0-5", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -149,10 +165,13 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, - lYAML: &lagoon.YAML{}, - mergedVariables: []lagoon.EnvironmentVariable{}, + lYAML: &lagoon.YAML{}, + mergedVariables: []lagoon.EnvironmentVariable{ + {Name: "LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG", Value: "enabled", Scope: "global"}, + }, }, vars: []helpers.EnvironmentVariable{ {Name: "LAGOON_FEATURE_BACKUP_PR_SCHEDULE", Value: "1,16,31,46 23 * * 0-5"}, @@ -160,11 +179,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 23 * * 0-5", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -180,21 +201,25 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, mergedVariables: []lagoon.EnvironmentVariable{ + {Name: "LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG", Value: "enabled", Scope: "global"}, {Name: "LAGOON_BACKUP_DEV_SCHEDULE", Value: "M/15 23 * * 0-5", Scope: "build"}, }, }, want: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 23 * * 0-5", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -210,10 +235,13 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, - lYAML: &lagoon.YAML{}, - mergedVariables: []lagoon.EnvironmentVariable{}, + lYAML: &lagoon.YAML{}, + mergedVariables: []lagoon.EnvironmentVariable{ + {Name: "LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG", Value: "enabled", Scope: "global"}, + }, }, vars: []helpers.EnvironmentVariable{ {Name: "LAGOON_FEATURE_BACKUP_DEV_SCHEDULE", Value: "1,16,31,46 23 * * 0-5"}, @@ -221,11 +249,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "pullrequest", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 23 * * 0-5", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -241,6 +271,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "production", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{ @@ -261,11 +292,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "production", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "1,16,31,46 0-23 1-31 1-12 0-6", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 10, Daily: 10, @@ -281,6 +314,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -292,9 +326,11 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ S3SecretName: "lagoon-baas-custom-backup-credentials", + S3BucketName: "baas-example-project", CustomLocation: CustomBackupRestoreLocation{ BackupLocationAccessKey: "abcdefg", BackupLocationSecretKey: "a1b2c3d4e5f6g7h8i9", @@ -317,6 +353,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -330,6 +367,7 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ S3SecretName: "lagoon-baas-custom-backup-credentials", @@ -357,6 +395,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -368,6 +407,7 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ CustomLocation: CustomBackupRestoreLocation{ @@ -377,6 +417,7 @@ func Test_generateBackupValues(t *testing.T) { BackupSchedule: "31 1 * * *", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -392,6 +433,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -407,6 +449,7 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ S3SecretName: "lagoon-baas-custom-backup-credentials", @@ -436,6 +479,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -447,11 +491,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "31 1 * * *", CheckSchedule: "@weekly-random", PruneSchedule: "@weekly-random", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, @@ -467,6 +513,7 @@ func Test_generateBackupValues(t *testing.T) { buildValues: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", }, lYAML: &lagoon.YAML{}, @@ -478,11 +525,13 @@ func Test_generateBackupValues(t *testing.T) { want: &BuildValues{ BuildType: "branch", EnvironmentType: "development", + Project: "example-project", Namespace: "example-com-main", Backup: BackupConfiguration{ BackupSchedule: "31 1 * * *", CheckSchedule: "31 4 * * 0", PruneSchedule: "31 4 * * 0", + S3BucketName: "baas-example-project", PruneRetention: PruneRetention{ Hourly: 0, Daily: 7, diff --git a/internal/templating/backups/template_schedule_test.go b/internal/templating/backups/template_schedule_test.go index f9946e9c..56cb8fb8 100644 --- a/internal/templating/backups/template_schedule_test.go +++ b/internal/templating/backups/template_schedule_test.go @@ -66,6 +66,7 @@ func TestGenerateBackupSchedule(t *testing.T) { BackupSchedule: "50 5 * * 6", CheckSchedule: "50 5 * * 6", PruneSchedule: "50 5 * * 6", + S3BucketName: "baas-example-project", PruneRetention: generator.PruneRetention{ Hourly: 0, Daily: 7, diff --git a/internal/templating/backups/test-resources/result-schedule2.yaml b/internal/templating/backups/test-resources/result-schedule2.yaml index 650c0b59..adcf631f 100644 --- a/internal/templating/backups/test-resources/result-schedule2.yaml +++ b/internal/templating/backups/test-resources/result-schedule2.yaml @@ -23,7 +23,8 @@ spec: repoPasswordSecretRef: key: repo-pw name: baas-repo-pw - s3: {} + s3: + bucket: baas-example-project backup: resources: {} schedule: 50 5 * * 6 diff --git a/test-resources/template-backups/test1-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test1-results/k8up-lagoon-backup-schedule.yaml index 3e637584..6944c64e 100644 --- a/test-resources/template-backups/test1-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test1-results/k8up-lagoon-backup-schedule.yaml @@ -23,7 +23,8 @@ spec: repoPasswordSecretRef: key: repo-pw name: baas-repo-pw - s3: {} + s3: + bucket: baas-example-project backup: resources: {} schedule: 5 23 * * * diff --git a/test-resources/template-backups/test2-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test2-results/k8up-lagoon-backup-schedule.yaml index c77cee9c..7a3de0e9 100644 --- a/test-resources/template-backups/test2-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test2-results/k8up-lagoon-backup-schedule.yaml @@ -23,7 +23,8 @@ spec: repoPasswordSecretRef: key: repo-pw name: baas-repo-pw - s3: {} + s3: + bucket: baas-example-project backup: resources: {} schedule: 1,31 23 * * * diff --git a/test-resources/template-backups/test3-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test3-results/k8up-lagoon-backup-schedule.yaml index fb7d7eaf..35be53be 100644 --- a/test-resources/template-backups/test3-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test3-results/k8up-lagoon-backup-schedule.yaml @@ -23,7 +23,8 @@ spec: repoPasswordSecretRef: key: repo-pw name: baas-repo-pw - s3: {} + s3: + bucket: baas-example-project backup: resources: {} schedule: 5 23 * * * diff --git a/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml index a0347951..d8325d48 100644 --- a/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml @@ -29,6 +29,7 @@ spec: accessKeyIDSecretRef: key: access-key name: lagoon-baas-custom-backup-credentials + bucket: baas-example-project secretAccessKeySecretRef: key: secret-key name: lagoon-baas-custom-backup-credentials diff --git a/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml index 02839739..fb8866a1 100644 --- a/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml @@ -25,7 +25,8 @@ spec: repoPasswordSecretRef: key: repo-pw name: baas-repo-pw - s3: {} + s3: + bucket: baas-example-project backup: resources: {} schedule: 3,33 12 * * * diff --git a/test-resources/template-backups/test6-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test6-results/k8up-lagoon-backup-schedule.yaml index c88ebf35..f5b6241a 100644 --- a/test-resources/template-backups/test6-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test6-results/k8up-lagoon-backup-schedule.yaml @@ -23,7 +23,8 @@ spec: repoPasswordSecretRef: key: repo-pw name: baas-repo-pw - s3: {} + s3: + bucket: baas-example-project backup: resources: {} schedule: 5,20,35,50 5 * * 0 From 9a400fb132b7a09ee99d6543d8da7972fb011f82 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Thu, 6 Oct 2022 14:05:41 +1100 Subject: [PATCH 06/17] chore: add api/kind to templates --- internal/templating/backups/template_schedule.go | 8 ++++++++ .../backups/test-resources/result-schedule3.yaml | 2 ++ .../backups/test-resources/result-schedule4.yaml | 2 ++ .../backups/test-resources/result-schedule5.yaml | 4 ++++ .../test4-results/k8up-lagoon-backup-schedule.yaml | 2 ++ .../test5-results/k8up-lagoon-backup-schedule.yaml | 2 ++ 6 files changed, 20 insertions(+) diff --git a/internal/templating/backups/template_schedule.go b/internal/templating/backups/template_schedule.go index 80a8ded0..f7d87b45 100644 --- a/internal/templating/backups/template_schedule.go +++ b/internal/templating/backups/template_schedule.go @@ -150,6 +150,10 @@ func GenerateBackupSchedule( result := append(separator[:], scheduleBytes[:]...) if lValues.Backup.CustomLocation.BackupLocationAccessKey != "" && lValues.Backup.CustomLocation.BackupLocationSecretKey != "" { backupSecret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: corev1.SchemeGroupVersion.Version, + }, ObjectMeta: metav1.ObjectMeta{ Name: "lagoon-baas-custom-backup-credentials", }, @@ -167,6 +171,10 @@ func GenerateBackupSchedule( } if lValues.Backup.CustomLocation.RestoreLocationAccessKey != "" && lValues.Backup.CustomLocation.RestoreLocationSecretKey != "" { restoreSecret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: corev1.SchemeGroupVersion.Version, + }, ObjectMeta: metav1.ObjectMeta{ Name: "lagoon-baas-custom-restore-credentials", }, diff --git a/internal/templating/backups/test-resources/result-schedule3.yaml b/internal/templating/backups/test-resources/result-schedule3.yaml index 3c5f2704..f2f5394f 100644 --- a/internal/templating/backups/test-resources/result-schedule3.yaml +++ b/internal/templating/backups/test-resources/result-schedule3.yaml @@ -48,6 +48,8 @@ spec: resourceRequirementsTemplate: {} status: {} --- +apiVersion: v1 +kind: Secret metadata: creationTimestamp: null name: lagoon-baas-custom-backup-credentials diff --git a/internal/templating/backups/test-resources/result-schedule4.yaml b/internal/templating/backups/test-resources/result-schedule4.yaml index 01acd148..0cde042c 100644 --- a/internal/templating/backups/test-resources/result-schedule4.yaml +++ b/internal/templating/backups/test-resources/result-schedule4.yaml @@ -48,6 +48,8 @@ spec: resourceRequirementsTemplate: {} status: {} --- +apiVersion: v1 +kind: Secret metadata: creationTimestamp: null name: lagoon-baas-custom-restore-credentials diff --git a/internal/templating/backups/test-resources/result-schedule5.yaml b/internal/templating/backups/test-resources/result-schedule5.yaml index fdd0b3be..71d55aad 100644 --- a/internal/templating/backups/test-resources/result-schedule5.yaml +++ b/internal/templating/backups/test-resources/result-schedule5.yaml @@ -48,6 +48,8 @@ spec: resourceRequirementsTemplate: {} status: {} --- +apiVersion: v1 +kind: Secret metadata: creationTimestamp: null name: lagoon-baas-custom-backup-credentials @@ -55,6 +57,8 @@ stringData: access-key: abc123 secret-key: abcdefghijklmnopqrstuvwxyz --- +apiVersion: v1 +kind: Secret metadata: creationTimestamp: null name: lagoon-baas-custom-restore-credentials diff --git a/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml index d8325d48..127f7099 100644 --- a/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test4-results/k8up-lagoon-backup-schedule.yaml @@ -49,6 +49,8 @@ spec: resourceRequirementsTemplate: {} status: {} --- +apiVersion: v1 +kind: Secret metadata: creationTimestamp: null name: lagoon-baas-custom-backup-credentials diff --git a/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml b/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml index fb8866a1..836f061e 100644 --- a/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml +++ b/test-resources/template-backups/test5-results/k8up-lagoon-backup-schedule.yaml @@ -43,6 +43,8 @@ spec: resourceRequirementsTemplate: {} status: {} --- +apiVersion: v1 +kind: Secret metadata: creationTimestamp: null name: lagoon-baas-custom-restore-credentials From 696018655bb5d78d05af57c1bec77a1d0a0c5ca1 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 28 Nov 2022 16:28:02 +1100 Subject: [PATCH 07/17] chore: support for v1 and v2 of k8up schedules --- Dockerfile | 2 +- cmd/template_backups.go | 6 + cmd/template_backups_test.go | 8 + go.mod | 58 +-- go.sum | 206 ++++------ internal/generator/buildvalues.go | 1 + internal/generator/generator.go | 3 + .../templating/backups/template_schedule.go | 359 ++++++++++++------ .../backups/template_schedule_test.go | 46 ++- .../test-resources/result-schedule6.yaml | 49 +++ legacy/build-deploy-docker-compose.sh | 18 +- 11 files changed, 475 insertions(+), 281 deletions(-) create mode 100644 internal/templating/backups/test-resources/result-schedule6.yaml diff --git a/Dockerfile b/Dockerfile index 9713d9bc..65e41792 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ ARG UPSTREAM_REPO ARG UPSTREAM_TAG ARG GO_VER FROM ${UPSTREAM_REPO:-uselagoon}/commons:${UPSTREAM_TAG:-latest} as commons -FROM golang:${GO_VER:-1.17}-alpine3.16 as golang +FROM golang:${GO_VER:-1.18}-alpine as golang RUN apk add --no-cache git RUN go install github.com/a8m/envsubst/cmd/envsubst@v1.2.0 diff --git a/cmd/template_backups.go b/cmd/template_backups.go index 17b96d29..97dbcab1 100644 --- a/cmd/template_backups.go +++ b/cmd/template_backups.go @@ -14,10 +14,15 @@ var backupGeneration = &cobra.Command{ Aliases: []string{"schedule", "bs"}, Short: "Generate the backup schedule templates for a Lagoon build", RunE: func(cmd *cobra.Command, args []string) error { + k8upVersion, err := cmd.Flags().GetString("version") + if err != nil { + return fmt.Errorf("error reading domain flag: %v", err) + } generator, err := generatorInput(true) if err != nil { return err } + generator.BackupConfiguration.K8upVersion = k8upVersion return BackupTemplateGeneration(generator) }, } @@ -43,4 +48,5 @@ func BackupTemplateGeneration(g generator.GeneratorInput, func init() { templateCmd.AddCommand(backupGeneration) + backupGeneration.Flags().StringP("version", "", "v1", "The version of k8up used.") } diff --git a/cmd/template_backups_test.go b/cmd/template_backups_test.go index 998d9df7..e16d07d5 100644 --- a/cmd/template_backups_test.go +++ b/cmd/template_backups_test.go @@ -36,6 +36,7 @@ func TestBackupTemplateGeneration(t *testing.T) { templatePath string controllerDevSchedule string controllerPRSchedule string + k8upVersion string } tests := []struct { name string @@ -54,6 +55,7 @@ func TestBackupTemplateGeneration(t *testing.T) { buildType: "branch", lagoonVersion: "v2.7.x", branch: "main", + k8upVersion: "v1", projectVars: `[{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test1/lagoon.yml", @@ -72,6 +74,7 @@ func TestBackupTemplateGeneration(t *testing.T) { buildType: "branch", lagoonVersion: "v2.7.x", branch: "main", + k8upVersion: "v1", projectVars: `[{"name":"LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG","value":"enabled","scope":"global"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test2/lagoon.yml", @@ -90,6 +93,7 @@ func TestBackupTemplateGeneration(t *testing.T) { buildType: "branch", lagoonVersion: "v2.7.x", branch: "main", + k8upVersion: "v1", projectVars: `[{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test3/lagoon.yml", @@ -111,6 +115,7 @@ func TestBackupTemplateGeneration(t *testing.T) { prBaseBranch: "main2", lagoonVersion: "v2.7.x", branch: "main", + k8upVersion: "v1", projectVars: `[{"name":"LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG","value":"enabled","scope":"global"},{"name":"LAGOON_BAAS_CUSTOM_BACKUP_ACCESS_KEY","value":"abcdefg","scope":"build"},{"name":"LAGOON_BAAS_CUSTOM_BACKUP_SECRET_KEY","value":"abcdefg1234567","scope":"build"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_BACKUP_PR_SCHEDULE","value":"3,33 12 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test4/lagoon.yml", @@ -132,6 +137,7 @@ func TestBackupTemplateGeneration(t *testing.T) { prBaseBranch: "main2", lagoonVersion: "v2.7.x", branch: "main", + k8upVersion: "v1", projectVars: `[{"name":"LAGOON_FEATURE_FLAG_CUSTOM_BACKUP_CONFIG","value":"enabled","scope":"global"},{"name":"LAGOON_BAAS_CUSTOM_RESTORE_ACCESS_KEY","value":"abcdefg","scope":"build"},{"name":"LAGOON_BAAS_CUSTOM_RESTORE_SECRET_KEY","value":"abcdefg1234567","scope":"build"},{"name":"LAGOON_BACKUP_DEV_SCHEDULE","value":"1,31 23 * * *","scope":"build"},{"name":"LAGOON_BACKUP_PR_SCHEDULE","value":"3,33 12 * * *","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test5/lagoon.yml", @@ -150,6 +156,7 @@ func TestBackupTemplateGeneration(t *testing.T) { buildType: "branch", lagoonVersion: "v2.7.x", branch: "main", + k8upVersion: "v1", projectVars: `[{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"},{"name":"LAGOON_FASTLY_SERVICE_IDS","value":"example.com:service-id:true:annotationscom","scope":"build"}]`, envVars: `[]`, lagoonYAML: "../test-resources/template-backups/test6/lagoon.yml", @@ -249,6 +256,7 @@ func TestBackupTemplateGeneration(t *testing.T) { RetryWaitMin: time.Duration(10) * time.Millisecond, RetryWaitMax: time.Duration(50) * time.Millisecond, }) + generator.BackupConfiguration.K8upVersion = tt.args.k8upVersion savedTemplates := tt.args.templatePath err = os.MkdirAll(tt.args.templatePath, 0755) diff --git a/go.mod b/go.mod index 93dec25d..d21bac92 100644 --- a/go.mod +++ b/go.mod @@ -1,69 +1,77 @@ module github.com/uselagoon/build-deploy-tool -go 1.17 +go 1.18 require ( github.com/PaesslerAG/gval v1.1.2 github.com/amazeeio/dbaas-operator v0.3.0 github.com/compose-spec/compose-go v1.2.7 github.com/cxmcc/unixsums v0.0.0-20131125091133-89564297d82f - github.com/google/go-cmp v0.5.7 + github.com/google/go-cmp v0.5.8 github.com/hashicorp/go-retryablehttp v0.5.4 github.com/imdario/mergo v0.3.13 - github.com/spf13/cobra v1.4.0 + github.com/k8up-io/k8up/v2 v2.5.2 + github.com/spf13/cobra v1.5.0 github.com/vshn/k8up v1.99.99 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.23.6 - k8s.io/apimachinery v0.23.6 - k8s.io/client-go v0.23.6 + k8s.io/api v0.25.3 + k8s.io/apimachinery v0.25.3 + k8s.io/client-go v0.25.3 sigs.k8s.io/yaml v1.3.0 ) require ( + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/go-logr/logr v1.2.0 // indirect + github.com/emicklei/go-restful/v3 v3.8.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.5 // indirect + github.com/go-openapi/swag v0.19.14 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gofuzz v1.1.0 // indirect - github.com/googleapis/gnostic v0.5.5 // indirect github.com/hashicorp/go-cleanhttp v0.5.1 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.7.1 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect - golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect - golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect + golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c // indirect + golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect + golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.0 // indirect - k8s.io/klog/v2 v2.30.0 // indirect - k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect - k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect - sigs.k8s.io/controller-runtime v0.9.6 // indirect - sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect + k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) replace github.com/compose-spec/compose-go v1.2.7 => github.com/shreddedbacon/compose-go v0.0.0-20220616064547-4e908a2865c1 diff --git a/go.sum b/go.sum index b908b10e..a883f095 100644 --- a/go.sum +++ b/go.sum @@ -13,11 +13,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -45,11 +40,9 @@ github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= @@ -58,7 +51,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -77,8 +69,10 @@ github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -97,6 +91,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= @@ -125,8 +120,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -145,7 +138,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -182,18 +175,17 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7fo github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -201,11 +193,9 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/firepear/qsplit/v2 v2.5.0/go.mod h1:Q65ZpyUdvAUkXISeeNtA3DPlDwEn9mHU/kzTtPUxmKQ= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -228,8 +218,9 @@ github.com/go-logr/glogr v0.1.0/go.mod h1:GDQ2+z9PAAX7+qBhL3FzAL2Nf8dxyliu0ppgJI github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= @@ -245,12 +236,15 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -275,6 +269,8 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= @@ -338,7 +334,6 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -346,7 +341,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -363,7 +357,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -385,7 +378,8 @@ github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -394,18 +388,16 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -413,10 +405,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -427,8 +415,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -487,19 +473,21 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.2.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -514,6 +502,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/k8up-io/k8up/v2 v2.5.2 h1:BsgmoagUfEw8Eni/WwquT45vG1NYWOLqXWxt/xtr5Rc= +github.com/k8up-io/k8up/v2 v2.5.2/go.mod h1:nvwkKA4Im3NqlZZiAGinQC+xB0geWKe0tVdBG9CCcoE= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -553,6 +543,8 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -612,6 +604,7 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -632,11 +625,11 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -644,8 +637,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= -github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI= github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= @@ -728,8 +721,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -744,8 +737,8 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -767,8 +760,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= @@ -805,7 +797,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yujunz/go-getter v1.4.1-lite/go.mod h1:sbmqxXjyLunH1PkF3n7zSlnVeMvmYUuIl9ZVs/7NyCc= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= @@ -823,8 +814,6 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -866,7 +855,6 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -891,7 +879,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -901,9 +888,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -949,32 +933,20 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c h1:JVAXQ10yGGVbSyoer5VILysz6YKjdNT2bsvlayjqhes= +golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1048,35 +1020,27 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U= +golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1085,7 +1049,6 @@ golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5f golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -1095,8 +1058,9 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1168,21 +1132,13 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -1204,11 +1160,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1248,18 +1199,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1276,12 +1217,6 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1294,8 +1229,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1335,14 +1270,14 @@ gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= -gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1355,8 +1290,8 @@ k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= k8s.io/api v0.18.10/go.mod h1:xWtwPX1v47j5RTncmlMFGCx8b0avh+nP8OgZZ9hjo3M= k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg= -k8s.io/api v0.23.6 h1:yOK34wbYECH4RsJbQ9sfkFK3O7f/DUHRlzFehkqZyVw= -k8s.io/api v0.23.6/go.mod h1:1kFaYxGCFHYp3qd6a85DAj/yW8aVD6XLZMqJclkoi9g= +k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ= +k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI= k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY= k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs= k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE= @@ -1365,8 +1300,8 @@ k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZ k8s.io/apimachinery v0.18.10/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI= -k8s.io/apimachinery v0.23.6 h1:RH1UweWJkWNTlFx0D8uxOpaU1tjIOvVVWV/bu5b3/NQ= -k8s.io/apimachinery v0.23.6/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= +k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg= k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA= k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU= @@ -1375,8 +1310,8 @@ k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= k8s.io/client-go v0.18.10/go.mod h1:XBkFAqPrzqfwmGkV5ac+mlgBpWcz5TkhLw2808q8C3c= k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE= k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU= -k8s.io/client-go v0.23.6 h1:7h4SctDVQAQbkHQnR4Kzi7EyUyvla5G1pFWf4+Od7hQ= -k8s.io/client-go v0.23.6/go.mod h1:Umt5icFOMLV/+qbtZ3PR0D+JA6lvvb3syzodv4irpK4= +k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0= +k8s.io/client-go v0.25.3/go.mod h1:t39LPczAIMwycjcXkVc+CB+PZV69jQuNx4um5ORDjQA= k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE= k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo= @@ -1388,33 +1323,30 @@ k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= -k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 h1:cTdVh7LYu82xeClmfzGtgyspNh6UxpwLWGi8R4sspNo= +k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= @@ -1429,27 +1361,27 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= -sigs.k8s.io/controller-runtime v0.9.6 h1:EevVMlgUj4fC1NVM4+DB3iPkWkmGRNarA66neqv9Qew= sigs.k8s.io/controller-runtime v0.9.6/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20210802150722-c0a5babc6854/go.mod h1:jqzBWjsNdxfl/cDmihB034I5aCqlfw2p24HYs3Eo4K4= sigs.k8s.io/controller-tools v0.2.2/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanIfnx6xsU70= sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUyp0jmnAM/I= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= sigs.k8s.io/kustomize/api v0.6.5/go.mod h1:Z96Z48h3nOWgVAmd4JGABszi5znhEnz7xoWHy+Bl7L4= sigs.k8s.io/kustomize/cmd/config v0.8.5/go.mod h1:PlZTWxL7Xi75mY64HBC9IVf2xwrEbzy3L7r7+19kON4= sigs.k8s.io/kustomize/kustomize/v3 v3.8.7/go.mod h1:EJBh54QBPZPSCJqfb9b+qGwzL9IE0Bp7hyM+wONC6Mw= sigs.k8s.io/kustomize/kyaml v0.9.4/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ= sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/internal/generator/buildvalues.go b/internal/generator/buildvalues.go index 6efd4b97..f18edb71 100644 --- a/internal/generator/buildvalues.go +++ b/internal/generator/buildvalues.go @@ -87,6 +87,7 @@ type CronjobValues struct { } type BackupConfiguration struct { + K8upVersion string `json:"k8upVersion"` PruneRetention PruneRetention `json:"pruneRetention"` PruneSchedule string `json:"pruneSchedule"` CheckSchedule string `json:"checkSchedule"` diff --git a/internal/generator/generator.go b/internal/generator/generator.go index 9f1aebcb..8ca054c0 100644 --- a/internal/generator/generator.go +++ b/internal/generator/generator.go @@ -46,6 +46,7 @@ type GeneratorInput struct { FastlyCacheNoCahce string FastlyAPISecretPrefix string SavedTemplatesPath string + BackupConfiguration BackupConfiguration IgnoreNonStringKeyErrors bool IgnoreMissingEnvFiles bool Debug bool @@ -84,6 +85,8 @@ func NewGenerator( fastlyAPISecretPrefix := helpers.GetEnv("ROUTE_FASTLY_SERVICE_ID", generator.FastlyAPISecretPrefix, generator.Debug) lagoonVersion := helpers.GetEnv("LAGOON_VERSION", generator.LagoonVersion, generator.Debug) + buildValues.Backup.K8upVersion = helpers.GetEnv("K8UP_VERSION", generator.BackupConfiguration.K8upVersion, generator.Debug) + // get the project and environment variables projectVariables := helpers.GetEnv("LAGOON_PROJECT_VARIABLES", generator.ProjectVariables, generator.Debug) environmentVariables := helpers.GetEnv("LAGOON_ENVIRONMENT_VARIABLES", generator.EnvironmentVariables, generator.Debug) diff --git a/internal/templating/backups/template_schedule.go b/internal/templating/backups/template_schedule.go index f7d87b45..4fbf3af0 100644 --- a/internal/templating/backups/template_schedule.go +++ b/internal/templating/backups/template_schedule.go @@ -5,6 +5,8 @@ import ( "github.com/uselagoon/build-deploy-tool/internal/generator" "github.com/uselagoon/build-deploy-tool/internal/helpers" + + k8upv1 "github.com/k8up-io/k8up/v2/api/v1" k8upv1alpha1 "github.com/vshn/k8up/api/v1alpha1" corev1 "k8s.io/api/core/v1" apivalidation "k8s.io/apimachinery/pkg/api/validation" @@ -18,136 +20,271 @@ func GenerateBackupSchedule( lValues generator.BuildValues, ) ([]byte, error) { // generate the template spec - s3Spec := &k8upv1alpha1.S3Spec{} - if lValues.Backup.S3Endpoint != "" { - s3Spec.Endpoint = lValues.Backup.S3Endpoint - } - if lValues.Backup.S3BucketName != "" { - s3Spec.Bucket = lValues.Backup.S3BucketName - } - if lValues.Backup.S3SecretName != "" { - s3Spec.AccessKeyIDSecretRef = &corev1.SecretKeySelector{ - Key: "access-key", - LocalObjectReference: corev1.LocalObjectReference{ - Name: lValues.Backup.S3SecretName, - }, + + var result []byte + separator := []byte("---\n") + + // create the schedule + switch lValues.Backup.K8upVersion { + case "v1": + s3Spec := &k8upv1alpha1.S3Spec{} + if lValues.Backup.S3Endpoint != "" { + s3Spec.Endpoint = lValues.Backup.S3Endpoint } - s3Spec.SecretAccessKeySecretRef = &corev1.SecretKeySelector{ - Key: "secret-key", - LocalObjectReference: corev1.LocalObjectReference{ - Name: lValues.Backup.S3SecretName, - }, + if lValues.Backup.S3BucketName != "" { + s3Spec.Bucket = lValues.Backup.S3BucketName } - } - // create the schedule - schedule := &k8upv1alpha1.Schedule{ - TypeMeta: metav1.TypeMeta{ - Kind: "Schedule", - APIVersion: k8upv1alpha1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "k8up-lagoon-backup-schedule", - }, - Spec: k8upv1alpha1.ScheduleSpec{ - Backend: &k8upv1alpha1.Backend{ - RepoPasswordSecretRef: &corev1.SecretKeySelector{ - Key: "repo-pw", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "baas-repo-pw", - }, + if lValues.Backup.S3SecretName != "" { + s3Spec.AccessKeyIDSecretRef = &corev1.SecretKeySelector{ + Key: "access-key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: lValues.Backup.S3SecretName, + }, + } + s3Spec.SecretAccessKeySecretRef = &corev1.SecretKeySelector{ + Key: "secret-key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: lValues.Backup.S3SecretName, }, - S3: s3Spec, + } + } + schedule := &k8upv1alpha1.Schedule{ + TypeMeta: metav1.TypeMeta{ + Kind: "Schedule", + APIVersion: k8upv1alpha1.GroupVersion.String(), }, - Backup: &k8upv1alpha1.BackupSchedule{ - ScheduleCommon: &k8upv1alpha1.ScheduleCommon{ - Schedule: k8upv1alpha1.ScheduleDefinition(lValues.Backup.BackupSchedule), + ObjectMeta: metav1.ObjectMeta{ + Name: "k8up-lagoon-backup-schedule", + }, + Spec: k8upv1alpha1.ScheduleSpec{ + Backend: &k8upv1alpha1.Backend{ + RepoPasswordSecretRef: &corev1.SecretKeySelector{ + Key: "repo-pw", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "baas-repo-pw", + }, + }, + S3: s3Spec, + }, + Backup: &k8upv1alpha1.BackupSchedule{ + ScheduleCommon: &k8upv1alpha1.ScheduleCommon{ + Schedule: k8upv1alpha1.ScheduleDefinition(lValues.Backup.BackupSchedule), + }, + }, + Check: &k8upv1alpha1.CheckSchedule{ + ScheduleCommon: &k8upv1alpha1.ScheduleCommon{ + Schedule: k8upv1alpha1.ScheduleDefinition(lValues.Backup.CheckSchedule), + }, + }, + Prune: &k8upv1alpha1.PruneSchedule{ + PruneSpec: k8upv1alpha1.PruneSpec{ + Retention: k8upv1alpha1.RetentionPolicy{ + KeepHourly: lValues.Backup.PruneRetention.Hourly, + KeepDaily: lValues.Backup.PruneRetention.Daily, + KeepWeekly: lValues.Backup.PruneRetention.Weekly, + KeepMonthly: lValues.Backup.PruneRetention.Monthly, + }, + }, + ScheduleCommon: &k8upv1alpha1.ScheduleCommon{ + Schedule: k8upv1alpha1.ScheduleDefinition(lValues.Backup.PruneSchedule), + }, }, }, - Check: &k8upv1alpha1.CheckSchedule{ - ScheduleCommon: &k8upv1alpha1.ScheduleCommon{ - Schedule: k8upv1alpha1.ScheduleDefinition(lValues.Backup.CheckSchedule), + } + // add the default labels + schedule.ObjectMeta.Labels = map[string]string{ + "app.kubernetes.io/name": "k8up-schedule", + "app.kubernetes.io/instance": "k8up-lagoon-backup-schedule", + "app.kubernetes.io/managed-by": "build-deploy-tool", + "lagoon.sh/template": fmt.Sprintf("%s-%s", "k8up-schedule", "0.1.0"), + "lagoon.sh/service": "k8up-lagoon-backup-schedule", + "lagoon.sh/service-type": "k8up-schedule", + "lagoon.sh/project": lValues.Project, + "lagoon.sh/environment": lValues.Environment, + "lagoon.sh/environmentType": lValues.EnvironmentType, + "lagoon.sh/buildType": lValues.BuildType, + } + + // add the default annotations + schedule.ObjectMeta.Annotations = map[string]string{ + "lagoon.sh/version": lValues.LagoonVersion, + } + + // add any additional labels + additionalLabels := map[string]string{} + additionalAnnotations := map[string]string{} + if lValues.BuildType == "branch" { + additionalAnnotations["lagoon.sh/branch"] = lValues.Branch + } else if lValues.BuildType == "pullrequest" { + additionalAnnotations["lagoon.sh/prNumber"] = lValues.PRNumber + additionalAnnotations["lagoon.sh/prHeadBranch"] = lValues.PRHeadBranch + additionalAnnotations["lagoon.sh/prBaseBranch"] = lValues.PRBaseBranch + + } + for key, value := range additionalLabels { + schedule.ObjectMeta.Labels[key] = value + } + // add any additional annotations + for key, value := range additionalAnnotations { + schedule.ObjectMeta.Annotations[key] = value + } + // validate any annotations + if err := apivalidation.ValidateAnnotations(schedule.ObjectMeta.Annotations, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the annotations for %s are not valid: %v", "k8up-lagoon-backup-schedule", err) + } + } + // validate any labels + if err := metavalidation.ValidateLabels(schedule.ObjectMeta.Labels, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the labels for %s are not valid: %v", "k8up-lagoon-backup-schedule", err) + } + } + + // check length of labels + err := helpers.CheckLabelLength(schedule.ObjectMeta.Labels) + if err != nil { + return nil, err + } + // @TODO: we should review this in the future when we stop doing `kubectl apply` in the builds :) + // marshal the resulting ingress + scheduleBytes, err := yaml.Marshal(schedule) + if err != nil { + return nil, err + } + // add the seperator to the template so that it can be `kubectl apply` in bulk as part + // of the current build process + result = append(separator[:], scheduleBytes[:]...) + case "v2": + s3Spec := &k8upv1.S3Spec{} + if lValues.Backup.S3Endpoint != "" { + s3Spec.Endpoint = lValues.Backup.S3Endpoint + } + if lValues.Backup.S3BucketName != "" { + s3Spec.Bucket = lValues.Backup.S3BucketName + } + if lValues.Backup.S3SecretName != "" { + s3Spec.AccessKeyIDSecretRef = &corev1.SecretKeySelector{ + Key: "access-key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: lValues.Backup.S3SecretName, + }, + } + s3Spec.SecretAccessKeySecretRef = &corev1.SecretKeySelector{ + Key: "secret-key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: lValues.Backup.S3SecretName, }, + } + } + schedule := &k8upv1.Schedule{ + TypeMeta: metav1.TypeMeta{ + Kind: "Schedule", + APIVersion: k8upv1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "k8up-lagoon-backup-schedule", }, - Prune: &k8upv1alpha1.PruneSchedule{ - PruneSpec: k8upv1alpha1.PruneSpec{ - Retention: k8upv1alpha1.RetentionPolicy{ - KeepHourly: lValues.Backup.PruneRetention.Hourly, - KeepDaily: lValues.Backup.PruneRetention.Daily, - KeepWeekly: lValues.Backup.PruneRetention.Weekly, - KeepMonthly: lValues.Backup.PruneRetention.Monthly, + Spec: k8upv1.ScheduleSpec{ + Backend: &k8upv1.Backend{ + RepoPasswordSecretRef: &corev1.SecretKeySelector{ + Key: "repo-pw", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "baas-repo-pw", + }, + }, + S3: s3Spec, + }, + Backup: &k8upv1.BackupSchedule{ + ScheduleCommon: &k8upv1.ScheduleCommon{ + Schedule: k8upv1.ScheduleDefinition(lValues.Backup.BackupSchedule), + }, + }, + Check: &k8upv1.CheckSchedule{ + ScheduleCommon: &k8upv1.ScheduleCommon{ + Schedule: k8upv1.ScheduleDefinition(lValues.Backup.CheckSchedule), }, }, - ScheduleCommon: &k8upv1alpha1.ScheduleCommon{ - Schedule: k8upv1alpha1.ScheduleDefinition(lValues.Backup.PruneSchedule), + Prune: &k8upv1.PruneSchedule{ + PruneSpec: k8upv1.PruneSpec{ + Retention: k8upv1.RetentionPolicy{ + KeepHourly: lValues.Backup.PruneRetention.Hourly, + KeepDaily: lValues.Backup.PruneRetention.Daily, + KeepWeekly: lValues.Backup.PruneRetention.Weekly, + KeepMonthly: lValues.Backup.PruneRetention.Monthly, + }, + }, + ScheduleCommon: &k8upv1.ScheduleCommon{ + Schedule: k8upv1.ScheduleDefinition(lValues.Backup.PruneSchedule), + }, }, }, - }, - } - // add the default labels - schedule.ObjectMeta.Labels = map[string]string{ - "app.kubernetes.io/name": "k8up-schedule", - "app.kubernetes.io/instance": "k8up-lagoon-backup-schedule", - "app.kubernetes.io/managed-by": "build-deploy-tool", - "lagoon.sh/template": fmt.Sprintf("%s-%s", "k8up-schedule", "0.1.0"), - "lagoon.sh/service": "k8up-lagoon-backup-schedule", - "lagoon.sh/service-type": "k8up-schedule", - "lagoon.sh/project": lValues.Project, - "lagoon.sh/environment": lValues.Environment, - "lagoon.sh/environmentType": lValues.EnvironmentType, - "lagoon.sh/buildType": lValues.BuildType, - } + } + // add the default labels + schedule.ObjectMeta.Labels = map[string]string{ + "app.kubernetes.io/name": "k8up-schedule", + "app.kubernetes.io/instance": "k8up-lagoon-backup-schedule", + "app.kubernetes.io/managed-by": "build-deploy-tool", + "lagoon.sh/template": fmt.Sprintf("%s-%s", "k8up-schedule", "0.1.0"), + "lagoon.sh/service": "k8up-lagoon-backup-schedule", + "lagoon.sh/service-type": "k8up-schedule", + "lagoon.sh/project": lValues.Project, + "lagoon.sh/environment": lValues.Environment, + "lagoon.sh/environmentType": lValues.EnvironmentType, + "lagoon.sh/buildType": lValues.BuildType, + } - // add the default annotations - schedule.ObjectMeta.Annotations = map[string]string{ - "lagoon.sh/version": lValues.LagoonVersion, - } + // add the default annotations + schedule.ObjectMeta.Annotations = map[string]string{ + "lagoon.sh/version": lValues.LagoonVersion, + } - // add any additional labels - additionalLabels := map[string]string{} - additionalAnnotations := map[string]string{} - if lValues.BuildType == "branch" { - additionalAnnotations["lagoon.sh/branch"] = lValues.Branch - } else if lValues.BuildType == "pullrequest" { - additionalAnnotations["lagoon.sh/prNumber"] = lValues.PRNumber - additionalAnnotations["lagoon.sh/prHeadBranch"] = lValues.PRHeadBranch - additionalAnnotations["lagoon.sh/prBaseBranch"] = lValues.PRBaseBranch + // add any additional labels + additionalLabels := map[string]string{} + additionalAnnotations := map[string]string{} + if lValues.BuildType == "branch" { + additionalAnnotations["lagoon.sh/branch"] = lValues.Branch + } else if lValues.BuildType == "pullrequest" { + additionalAnnotations["lagoon.sh/prNumber"] = lValues.PRNumber + additionalAnnotations["lagoon.sh/prHeadBranch"] = lValues.PRHeadBranch + additionalAnnotations["lagoon.sh/prBaseBranch"] = lValues.PRBaseBranch - } - for key, value := range additionalLabels { - schedule.ObjectMeta.Labels[key] = value - } - // add any additional annotations - for key, value := range additionalAnnotations { - schedule.ObjectMeta.Annotations[key] = value - } - // validate any annotations - if err := apivalidation.ValidateAnnotations(schedule.ObjectMeta.Annotations, nil); err != nil { - if len(err) != 0 { - return nil, fmt.Errorf("the annotations for %s are not valid: %v", "k8up-lagoon-backup-schedule", err) } - } - // validate any labels - if err := metavalidation.ValidateLabels(schedule.ObjectMeta.Labels, nil); err != nil { - if len(err) != 0 { - return nil, fmt.Errorf("the labels for %s are not valid: %v", "k8up-lagoon-backup-schedule", err) + for key, value := range additionalLabels { + schedule.ObjectMeta.Labels[key] = value + } + // add any additional annotations + for key, value := range additionalAnnotations { + schedule.ObjectMeta.Annotations[key] = value + } + // validate any annotations + if err := apivalidation.ValidateAnnotations(schedule.ObjectMeta.Annotations, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the annotations for %s are not valid: %v", "k8up-lagoon-backup-schedule", err) + } + } + // validate any labels + if err := metavalidation.ValidateLabels(schedule.ObjectMeta.Labels, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the labels for %s are not valid: %v", "k8up-lagoon-backup-schedule", err) + } } - } - // check length of labels - err := helpers.CheckLabelLength(schedule.ObjectMeta.Labels) - if err != nil { - return nil, err - } - // @TODO: we should review this in the future when we stop doing `kubectl apply` in the builds :) - // marshal the resulting ingress - scheduleBytes, err := yaml.Marshal(schedule) - if err != nil { - return nil, err + // check length of labels + err := helpers.CheckLabelLength(schedule.ObjectMeta.Labels) + if err != nil { + return nil, err + } + // @TODO: we should review this in the future when we stop doing `kubectl apply` in the builds :) + // marshal the resulting ingress + scheduleBytes, err := yaml.Marshal(schedule) + if err != nil { + return nil, err + } + // add the seperator to the template so that it can be `kubectl apply` in bulk as part + // of the current build process + result = append(separator[:], scheduleBytes[:]...) } - // add the seperator to the template so that it can be `kubectl apply` in bulk as part - // of the current build process - separator := []byte("---\n") - result := append(separator[:], scheduleBytes[:]...) if lValues.Backup.CustomLocation.BackupLocationAccessKey != "" && lValues.Backup.CustomLocation.BackupLocationSecretKey != "" { backupSecret := &corev1.Secret{ TypeMeta: metav1.TypeMeta{ diff --git a/internal/templating/backups/template_schedule_test.go b/internal/templating/backups/template_schedule_test.go index 56cb8fb8..2a098cdd 100644 --- a/internal/templating/backups/template_schedule_test.go +++ b/internal/templating/backups/template_schedule_test.go @@ -21,7 +21,7 @@ func TestGenerateBackupSchedule(t *testing.T) { wantErr bool }{ { - name: "test1", + name: "test1 - k8up/v1alpha1", args: args{ lValues: generator.BuildValues{ Project: "example-project", @@ -33,6 +33,7 @@ func TestGenerateBackupSchedule(t *testing.T) { Kubernetes: "generator.local", Branch: "environment-with-really-really-reall-3fdb", Backup: generator.BackupConfiguration{ + K8upVersion: "v1", S3Endpoint: "https://minio.endpoint", S3BucketName: "my-bucket", S3SecretName: "my-s3-secret", @@ -51,7 +52,7 @@ func TestGenerateBackupSchedule(t *testing.T) { want: "test-resources/result-schedule1.yaml", }, { - name: "test2", + name: "test2 - k8up/v1alpha1", args: args{ lValues: generator.BuildValues{ Project: "example-project", @@ -63,6 +64,7 @@ func TestGenerateBackupSchedule(t *testing.T) { Kubernetes: "generator.local", Branch: "environment-with-really-really-reall-3fdb", Backup: generator.BackupConfiguration{ + K8upVersion: "v1", BackupSchedule: "50 5 * * 6", CheckSchedule: "50 5 * * 6", PruneSchedule: "50 5 * * 6", @@ -79,7 +81,7 @@ func TestGenerateBackupSchedule(t *testing.T) { want: "test-resources/result-schedule2.yaml", }, { - name: "test3", + name: "test3 - k8up/v1alpha1", args: args{ lValues: generator.BuildValues{ Project: "example-project", @@ -91,6 +93,7 @@ func TestGenerateBackupSchedule(t *testing.T) { Kubernetes: "generator.local", Branch: "environment-with-really-really-reall-3fdb", Backup: generator.BackupConfiguration{ + K8upVersion: "v1", S3Endpoint: "https://minio.endpoint", S3BucketName: "my-bucket", S3SecretName: "my-s3-secret", @@ -113,7 +116,7 @@ func TestGenerateBackupSchedule(t *testing.T) { want: "test-resources/result-schedule3.yaml", }, { - name: "test4", + name: "test4 - k8up/v1alpha1", args: args{ lValues: generator.BuildValues{ Project: "example-project", @@ -125,6 +128,7 @@ func TestGenerateBackupSchedule(t *testing.T) { Kubernetes: "generator.local", Branch: "environment-with-really-really-reall-3fdb", Backup: generator.BackupConfiguration{ + K8upVersion: "v1", S3Endpoint: "https://minio.endpoint", S3BucketName: "my-bucket", S3SecretName: "my-s3-secret", @@ -147,7 +151,7 @@ func TestGenerateBackupSchedule(t *testing.T) { want: "test-resources/result-schedule4.yaml", }, { - name: "test5", + name: "test5 - k8up/v1alpha1", args: args{ lValues: generator.BuildValues{ Project: "example-project", @@ -159,6 +163,7 @@ func TestGenerateBackupSchedule(t *testing.T) { Kubernetes: "generator.local", Branch: "environment-with-really-really-reall-3fdb", Backup: generator.BackupConfiguration{ + K8upVersion: "v1", S3Endpoint: "https://minio.endpoint", S3BucketName: "my-bucket", S3SecretName: "my-s3-secret", @@ -182,6 +187,37 @@ func TestGenerateBackupSchedule(t *testing.T) { }, want: "test-resources/result-schedule5.yaml", }, + { + name: "test6 - k8up/v1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Backup: generator.BackupConfiguration{ + K8upVersion: "v2", + S3Endpoint: "https://minio.endpoint", + S3BucketName: "my-bucket", + S3SecretName: "my-s3-secret", + BackupSchedule: "50 5 * * 6", + CheckSchedule: "50 5 * * 6", + PruneSchedule: "50 5 * * 6", + PruneRetention: generator.PruneRetention{ + Hourly: 0, + Daily: 7, + Weekly: 6, + Monthly: 1, + }, + }, + }, + }, + want: "test-resources/result-schedule6.yaml", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/templating/backups/test-resources/result-schedule6.yaml b/internal/templating/backups/test-resources/result-schedule6.yaml new file mode 100644 index 00000000..fc0ab823 --- /dev/null +++ b/internal/templating/backups/test-resources/result-schedule6.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: k8up.io/v1 +kind: Schedule +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: k8up-lagoon-backup-schedule + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: k8up-schedule + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: k8up-lagoon-backup-schedule + lagoon.sh/service-type: k8up-schedule + lagoon.sh/template: k8up-schedule-0.1.0 + name: k8up-lagoon-backup-schedule +spec: + backend: + repoPasswordSecretRef: + key: repo-pw + name: baas-repo-pw + s3: + accessKeyIDSecretRef: + key: access-key + name: my-s3-secret + bucket: my-bucket + endpoint: https://minio.endpoint + secretAccessKeySecretRef: + key: secret-key + name: my-s3-secret + backup: + resources: {} + schedule: 50 5 * * 6 + check: + resources: {} + schedule: 50 5 * * 6 + prune: + resources: {} + retention: + keepDaily: 7 + keepMonthly: 1 + keepWeekly: 6 + schedule: 50 5 * * 6 + resourceRequirementsTemplate: {} +status: {} diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index 9036484b..83b0a550 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -1069,12 +1069,26 @@ set -x # Run the backup generation script # build-tool doesn't do any capability checks yet, so do this for now -if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then +if [[ "${CAPABILITIES[@]}" =~ "k8up.io/v1/Schedule" ]]; then if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then # Create baas-repo-pw secret based on the project secret kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) fi - build-deploy-tool template backup-schedule + build-deploy-tool template backup-schedule --version v2 + # check if the existing schedule exists, and delete it + if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then + if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get schedules.backup.appuio.ch k8up-lagoon-backup-schedule &> /dev/null; then + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete schedules.backup.appuio.ch k8up-lagoon-backup-schedule + fi + fi + K8UP_VERSION="v2" +fi +if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]] && [[ "$K8UP_VERSION" != "v2" ]]; then + if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then + # Create baas-repo-pw secret based on the project secret + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) + fi + build-deploy-tool template backup-schedule --version v1 fi # check for ISOLATION_NETWORK_POLICY feature flag, disabled by default From 8039684ae34f8635036e19cf8cd3f8db1df29eb9 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 28 Nov 2022 16:35:09 +1100 Subject: [PATCH 08/17] chore: update go version in dockerfile --- legacy/Dockerfile.kubectl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legacy/Dockerfile.kubectl b/legacy/Dockerfile.kubectl index 4454b974..aa8b3ab6 100644 --- a/legacy/Dockerfile.kubectl +++ b/legacy/Dockerfile.kubectl @@ -1,7 +1,7 @@ ARG UPSTREAM_REPO ARG UPSTREAM_TAG FROM ${UPSTREAM_REPO:-uselagoon}/commons:${UPSTREAM_TAG:-latest} as commons -FROM golang:1.16-alpine3.15 as golang +FROM golang:1.18-alpine as golang RUN apk add --no-cache git RUN go get github.com/a8m/envsubst/cmd/envsubst From 59e52f98601971639ef301b301e9166e8e4e8bc5 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 28 Nov 2022 16:56:46 +1100 Subject: [PATCH 09/17] chore: update go versions --- .github/workflows/build.yaml | 2 +- .github/workflows/docker-image.yaml | 2 +- .github/workflows/lagoon-core-docker-image.yaml | 2 +- .github/workflows/release.yaml | 4 ++-- .github/workflows/tag-to-release.yaml | 2 +- .github/workflows/test.yaml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5c79a36b..ed7ca6e5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -13,7 +13,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: "^1.17" + go-version: "^1.18" - name: Set up environment run: echo "GOVERSION=$(go version)" >> $GITHUB_ENV - name: Run GoReleaser diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 6cde28ad..09529fb7 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -17,7 +17,7 @@ jobs: strategy: matrix: goversion: - - 1.17 + - 1.18 steps: - name: Checkout PR diff --git a/.github/workflows/lagoon-core-docker-image.yaml b/.github/workflows/lagoon-core-docker-image.yaml index 89987af4..66ed650a 100644 --- a/.github/workflows/lagoon-core-docker-image.yaml +++ b/.github/workflows/lagoon-core-docker-image.yaml @@ -11,7 +11,7 @@ jobs: strategy: matrix: goversion: - - 1.17 + - 1.18 steps: - name: Checkout Branch or Tag diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f86093dc..c67376c5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,7 +20,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: "^1.17" + go-version: "^1.18" - name: Install ccv run: > curl -sSL https://github.com/smlx/ccv/releases/download/v0.3.2/ccv_0.3.2_linux_amd64.tar.gz @@ -49,7 +49,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: "^1.17" + go-version: "^1.18" - name: Set up environment run: echo "GOVERSION=$(go version)" >> $GITHUB_ENV - name: Run GoReleaser diff --git a/.github/workflows/tag-to-release.yaml b/.github/workflows/tag-to-release.yaml index 5fe339d6..9e5971e2 100644 --- a/.github/workflows/tag-to-release.yaml +++ b/.github/workflows/tag-to-release.yaml @@ -16,7 +16,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: "^1.17" + go-version: "^1.18" - name: Set up environment run: echo "GOVERSION=$(go version)" >> $GITHUB_ENV - name: Run GoReleaser diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f2fc8eb5..e1aca77e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -9,6 +9,6 @@ jobs: - name: Install Go uses: actions/setup-go@v2 with: - go-version: "^1.17" + go-version: "^1.18" - name: Run Tests run: go test -v ./... From aa148c64ca6dd1d0f8dce8411cdd5dae8928e5c8 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Fri, 2 Dec 2022 15:25:14 +1100 Subject: [PATCH 10/17] chore: add some basic service defaults and support for additional lagoon labels, generate prebackuppod templates --- cmd/template_backups.go | 6 + cmd/template_backups_test.go | 7 +- go.mod | 3 +- go.sum | 6 +- internal/generator/buildvalues.go | 70 ++-- internal/generator/generator.go | 11 + internal/generator/services.go | 75 +++- internal/generator/services_test.go | 25 ++ internal/helpers/helpers.go | 15 + .../backups/template_prebackuppod.go | 392 ++++++++++++++++++ .../backups/template_prebackuppod_test.go | 213 ++++++++++ .../test-resources/result-prebackuppod1.yaml | 78 ++++ .../test-resources/result-prebackuppod2.yaml | 61 +++ .../test-resources/result-prebackuppod3.yaml | 60 +++ .../test-resources/result-prebackuppod4.yaml | 48 +++ .../test-resources/result-prebackuppod5.yaml | 48 +++ .../test-resources/result-prebackuppod6.yaml | 48 +++ .../elasticsearch/templates/prebackuppod.yaml | 48 --- .../mariadb-dbaas/templates/prebackuppod.yaml | 66 --- .../mongodb-dbaas/templates/prebackuppod.yaml | 67 --- .../opensearch/templates/prebackuppod.yaml | 48 --- .../templates/prebackuppod.yaml | 52 --- .../test1-results/prebackuppods.yaml | 126 ++++++ .../template-backups/test1/docker-compose.yml | 24 +- .../test2-results/prebackuppods.yaml | 0 .../test3-results/prebackuppods.yaml | 0 .../test4-results/prebackuppods.yaml | 0 .../test5-results/prebackuppods.yaml | 0 .../test6-results/prebackuppods.yaml | 0 29 files changed, 1280 insertions(+), 317 deletions(-) create mode 100644 internal/templating/backups/template_prebackuppod.go create mode 100644 internal/templating/backups/template_prebackuppod_test.go create mode 100644 internal/templating/backups/test-resources/result-prebackuppod1.yaml create mode 100644 internal/templating/backups/test-resources/result-prebackuppod2.yaml create mode 100644 internal/templating/backups/test-resources/result-prebackuppod3.yaml create mode 100644 internal/templating/backups/test-resources/result-prebackuppod4.yaml create mode 100644 internal/templating/backups/test-resources/result-prebackuppod5.yaml create mode 100644 internal/templating/backups/test-resources/result-prebackuppod6.yaml delete mode 100644 legacy/helmcharts/elasticsearch/templates/prebackuppod.yaml delete mode 100644 legacy/helmcharts/mariadb-dbaas/templates/prebackuppod.yaml delete mode 100644 legacy/helmcharts/mongodb-dbaas/templates/prebackuppod.yaml delete mode 100644 legacy/helmcharts/opensearch/templates/prebackuppod.yaml delete mode 100644 legacy/helmcharts/postgres-dbaas/templates/prebackuppod.yaml create mode 100644 test-resources/template-backups/test1-results/prebackuppods.yaml create mode 100644 test-resources/template-backups/test2-results/prebackuppods.yaml create mode 100644 test-resources/template-backups/test3-results/prebackuppods.yaml create mode 100644 test-resources/template-backups/test4-results/prebackuppods.yaml create mode 100644 test-resources/template-backups/test5-results/prebackuppods.yaml create mode 100644 test-resources/template-backups/test6-results/prebackuppods.yaml diff --git a/cmd/template_backups.go b/cmd/template_backups.go index 97dbcab1..db33ddba 100644 --- a/cmd/template_backups.go +++ b/cmd/template_backups.go @@ -43,6 +43,12 @@ func BackupTemplateGeneration(g generator.GeneratorInput, return fmt.Errorf("couldn't generate template: %v", err) } helpers.WriteTemplateFile(fmt.Sprintf("%s/%s.yaml", savedTemplates, "k8up-lagoon-backup-schedule"), templateYAML) + + templateYAML, err = backuptemplate.GeneratePreBackupPod(*lagoonBuild.BuildValues) + if err != nil { + return fmt.Errorf("couldn't generate template: %v", err) + } + helpers.WriteTemplateFile(fmt.Sprintf("%s/%s.yaml", savedTemplates, "prebackuppods"), templateYAML) return nil } diff --git a/cmd/template_backups_test.go b/cmd/template_backups_test.go index e16d07d5..30d4f325 100644 --- a/cmd/template_backups_test.go +++ b/cmd/template_backups_test.go @@ -265,7 +265,12 @@ func TestBackupTemplateGeneration(t *testing.T) { } defer os.RemoveAll(savedTemplates) - defer os.RemoveAll(savedTemplates) + ts := dbaasclient.TestDBaaSHTTPServer() + defer ts.Close() + err = os.Setenv("DBAAS_OPERATOR_HTTP", ts.URL) + if err != nil { + t.Errorf("%v", err) + } if err := BackupTemplateGeneration(generator); (err != nil) != tt.wantErr { t.Errorf("BackupTemplateGeneration() error = %v, wantErr %v", err, tt.wantErr) diff --git a/go.mod b/go.mod index d21bac92..9c8a7e66 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,12 @@ require ( github.com/amazeeio/dbaas-operator v0.3.0 github.com/compose-spec/compose-go v1.2.7 github.com/cxmcc/unixsums v0.0.0-20131125091133-89564297d82f - github.com/google/go-cmp v0.5.8 + github.com/google/go-cmp v0.5.9 github.com/hashicorp/go-retryablehttp v0.5.4 github.com/imdario/mergo v0.3.13 github.com/k8up-io/k8up/v2 v2.5.2 github.com/spf13/cobra v1.5.0 + github.com/uselagoon/machinery v0.0.7 github.com/vshn/k8up v1.99.99 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.25.3 diff --git a/go.sum b/go.sum index a883f095..f5d55603 100644 --- a/go.sum +++ b/go.sum @@ -390,8 +390,8 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= @@ -773,6 +773,8 @@ github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lP github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/uselagoon/machinery v0.0.7 h1:fBIURDQRVnaB/Gime1Lfp6kgQYmuQpa0gmdfPwo7dkc= +github.com/uselagoon/machinery v0.0.7/go.mod h1:dGAvkxWQkRu/eLQeWLrTl5HvNoFsiXlXInCptHUxzUw= github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= diff --git a/internal/generator/buildvalues.go b/internal/generator/buildvalues.go index f18edb71..c625f01f 100644 --- a/internal/generator/buildvalues.go +++ b/internal/generator/buildvalues.go @@ -3,40 +3,32 @@ package generator import ( "github.com/uselagoon/build-deploy-tool/internal/dbaasclient" "github.com/uselagoon/build-deploy-tool/internal/lagoon" + corev1 "k8s.io/api/core/v1" ) // BuildValues is the values file data generated by the lagoon build type BuildValues struct { - Project string `json:"project"` - Environment string `json:"environment"` - EnvironmentType string `json:"environmentType"` - Namespace string `json:"namespace"` - GitSha string `json:"gitSha"` - BuildType string `json:"buildType"` - Kubernetes string `json:"kubernetes"` - LagoonVersion string `json:"lagoonVersion"` - ActiveEnvironment string `json:"activeEnvironment"` - StandbyEnvironment string `json:"standbyEnvironment"` - IsActiveEnvironment bool `json:"isActiveEnvironment"` - IsStandbyEnvironment bool `json:"isStandbyEnvironment"` - PodSecurityContext struct { - FsGroup int `json:"fsGroup"` - RunAsGroup int `json:"runAsGroup"` - RunAsUser int `json:"runAsUser"` - } `json:"podSecurityContext"` - ImagePullSecrets []struct { - Name string `json:"name"` - } `json:"imagePullSecrets"` - Branch string `json:"branch"` - PRNumber string `json:"prNumber"` - PRTitle string `json:"prTitle"` - PRHeadBranch string `json:"prHeadBranch"` - PRBaseBranch string `json:"prBaseBranch"` - Fastly struct { - ServiceID string `json:"serviceId"` - APISecretName string `json:"apiSecretName"` - Watch bool `json:"watch"` - } `json:"fastly"` + Project string `json:"project"` + Environment string `json:"environment"` + EnvironmentType string `json:"environmentType"` + Namespace string `json:"namespace"` + GitSha string `json:"gitSha"` + BuildType string `json:"buildType"` + Kubernetes string `json:"kubernetes"` + LagoonVersion string `json:"lagoonVersion"` + ActiveEnvironment string `json:"activeEnvironment"` + StandbyEnvironment string `json:"standbyEnvironment"` + IsActiveEnvironment bool `json:"isActiveEnvironment"` + IsStandbyEnvironment bool `json:"isStandbyEnvironment"` + PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext"` + ImagePullSecrets []string `json:"imagePullSecrets"` + PrivateRegistryURLS []string `json:"privateRegistryURLS"` + Branch string `json:"branch"` + PRNumber string `json:"prNumber"` + PRTitle string `json:"prTitle"` + PRHeadBranch string `json:"prHeadBranch"` + PRBaseBranch string `json:"prBaseBranch"` + Fastly Fastly `json:"fastly"` FastlyCacheNoCache string `json:"fastlyCacheNoCahce"` FastlyAPISecretPrefix string `json:"fastlyAPISecretPrefix"` ConfigMapSha string `json:"configMapSha"` @@ -58,6 +50,12 @@ type BuildValues struct { DBaaSClient *dbaasclient.Client `json:"-"` } +type Fastly struct { + ServiceID string `json:"serviceId"` + APISecretName string `json:"apiSecretName"` + Watch bool `json:"watch"` +} + type MonitoringConfig struct { Enabled bool `json:"enabled"` AlertContact string `json:"alertContact"` @@ -78,6 +76,18 @@ type ServiceValues struct { InPodCronjobs string `json:"inPodCronjobs"` ImageName string `json:"imageName"` DeploymentServiceType string `json:"deploymentServiecType"` + ServicePort int32 `json:"servicePort,omitempty"` + PersistentVolumePath string `json:"persistentVolumePath,omitempty"` + PersistentVolumeName string `json:"persistentVolumeName,omitempty"` + PersistentVolumeSize string `json:"persistentVolumeSize,omitempty"` + UseSpotInstances bool `json:"useSpot"` + NodeSelectors *map[string]string `json:"nodeSelectors"` + Tolerations *[]corev1.Toleration `json:"tolerations"` + Affinity *corev1.Affinity `json:"affinity"` + CronjobUseSpotInstances bool `json:"cronjobUseSpot"` + CronjobNodeSelectors *map[string]string `json:"cronjobNodeSelectors"` + CronjobTolerations *[]corev1.Toleration `json:"cronjobTolerations"` + CronjobAffinity *corev1.Affinity `json:"cronjobAffinity"` } // CronjobValues is the values for cronjobs diff --git a/internal/generator/generator.go b/internal/generator/generator.go index 8ca054c0..e850c5a2 100644 --- a/internal/generator/generator.go +++ b/internal/generator/generator.go @@ -10,6 +10,8 @@ import ( "github.com/uselagoon/build-deploy-tool/internal/dbaasclient" "github.com/uselagoon/build-deploy-tool/internal/helpers" "github.com/uselagoon/build-deploy-tool/internal/lagoon" + "github.com/uselagoon/machinery/utils/conversion" + corev1 "k8s.io/api/core/v1" "sigs.k8s.io/yaml" ) @@ -203,6 +205,15 @@ func NewGenerator( } } + rootlessWorkloads := CheckFeatureFlag("ROOTLESS_WORKLOAD", lagoonEnvVars, generator.Debug) + if rootlessWorkloads == "enabled" { + buildValues.PodSecurityContext = &corev1.PodSecurityContext{ + FSGroup: conversion.Int64Ptr(10001), + RunAsGroup: conversion.Int64Ptr(0), + RunAsUser: conversion.Int64Ptr(10000), + } + } + // @TODO: eventually fail builds if this is not set https://github.com/uselagoon/build-deploy-tool/issues/56 // lagoonDBaaSFallbackSingle, _ := lagoon.GetLagoonVariable("LAGOON_FEATURE_FLAG_DBAAS_FALLBACK_SINGLE", nil, lagoonEnvVars) // buildValues.DBaaSFallbackSingle = helpers.StrToBool(lagoonDBaaSFallbackSingle.Value) diff --git a/internal/generator/services.go b/internal/generator/services.go index e7f57d19..a9f982a5 100644 --- a/internal/generator/services.go +++ b/internal/generator/services.go @@ -35,6 +35,42 @@ var supportedAutogeneratedTypes = []string{ "python", } +// just some default values for services +var defaultServiceValues = map[string]map[string]string{ + "elasticsearch": map[string]string{ + "persistentPath": "/usr/share/elasticsearch/data", + "persistentSize": "5Gi", + }, + "opensearch": map[string]string{ + "persistentPath": "/usr/share/opensearch/data", + "persistentSize": "5Gi", + }, + "mariadb-single": map[string]string{ + "persistentPath": "/var/lib/mysql", + "persistentSize": "5Gi", + }, + "postgres-single": map[string]string{ + "persistentPath": "/var/lib/postgresql/data", + "persistentSize": "5Gi", + }, + "mongodb-single": map[string]string{ + "persistentPath": "/data/db", + "persistentSize": "5Gi", + }, + "varnish-persistent": map[string]string{ + "persistentPath": "/var/cache/varnish", + "persistentSize": "5Gi", + }, + "rabbitmq": map[string]string{ + "persistentPath": "/var/lib/rabbitmq", + "persistentSize": "5Gi", + }, + "redis-persistent": map[string]string{ + "persistentPath": "/data", + "persistentSize": "5Gi", + }, +} + // generateServicesFromDockerCompose unmarshals the docker-compose file and processes the services using composeToServiceValues func generateServicesFromDockerCompose( buildValues *BuildValues, @@ -150,6 +186,7 @@ func composeToServiceValues( if serviceDeploymentServiceType == "" { serviceDeploymentServiceType = composeService } + // if there is a `lagoon.name` label on this service, this should be used as an override name lagoonOverrideName := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, "lagoon.name") if lagoonOverrideName != "" { @@ -166,6 +203,27 @@ func composeToServiceValues( lagoonOverrideName = composeService } + // check if the service has any persistent labels + servicePersistentPath := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, "lagoon.persistent") + if servicePersistentPath == "" { + // if there is no persistent path, check if the service type has a default + if val, ok := defaultServiceValues[lagoonType]; ok { + servicePersistentPath = val["persistentPath"] + } + } + servicePersistentName := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, "lagoon.persistent.name") + if servicePersistentName == "" && servicePersistentPath != "" { + // if there is a persistent path defined, then set the persistent name to be the compose service if no persistent name is provided + servicePersistentName = composeService + } + servicePersistentSize := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, "lagoon.persistent.size") + if servicePersistentSize == "" { + // if there is no persistent size, check if the service type has a default + if val, ok := defaultServiceValues[lagoonType]; ok { + servicePersistentSize = val["persistentSize"] + } + } + // if there are overrides defined in the lagoon API `LAGOON_SERVICE_TYPES` // handle those here if buildValues.ServiceTypeOverrides != nil { @@ -207,7 +265,7 @@ func composeToServiceValues( // elif [[ "${CAPABILITIES[@]}" =~ "mariadb.amazee.io/v1/MariaDBConsumer" ]] && ! checkDBaaSHealth ; then lagoonType = fmt.Sprintf("%s-single", lagoonType) } else { - // if there is a `lagoon.name` label on this service, this should be used as an override name + // if there is a `lagoon.%s-dbaas.environment` label on this service, this should be used as an the environment type for the dbaas dbaasLabelOverride := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, fmt.Sprintf("lagoon.%s-dbaas.environment", lagoonType)) if dbaasLabelOverride != "" { dbaasEnvironment = dbaasLabelOverride @@ -259,6 +317,21 @@ func composeToServiceValues( AutogeneratedRoutesEnabled: autogenEnabled, AutogeneratedRoutesTLSAcme: autogenTLSAcmeEnabled, DBaaSEnvironment: dbaasEnvironment, + PersistentVolumePath: servicePersistentPath, + PersistentVolumeName: servicePersistentName, + PersistentVolumeSize: servicePersistentSize, + } + // check if the service has a service port override (this only applies to basic(-persistent)) + servicePortOverride := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, "lagoon.service.port") + if servicePortOverride != "" { + sPort, err := strconv.Atoi(servicePortOverride) + if err != nil { + return ServiceValues{}, fmt.Errorf( + "The provided service port %s for service %s is not a valid integer: %v", + servicePortOverride, composeService, err, + ) + } + cService.ServicePort = int32(sPort) } return cService, nil } diff --git a/internal/generator/services_test.go b/internal/generator/services_test.go index 87a0c2df..e1b211d5 100644 --- a/internal/generator/services_test.go +++ b/internal/generator/services_test.go @@ -459,6 +459,31 @@ func Test_composeToServiceValues(t *testing.T) { AutogeneratedRoutesTLSAcme: true, }, }, + { + name: "test14 - invalid service port", + args: args{ + lYAML: &lagoon.YAML{ + Environments: lagoon.Environments{ + "main": lagoon.Environment{}, + }, + }, + buildValues: &BuildValues{ + Environment: "main", + Branch: "main", + BuildType: "branch", + ServiceTypeOverrides: &lagoon.EnvironmentVariable{}, + }, + composeService: "basic", + composeServiceValues: composetypes.ServiceConfig{ + Labels: composetypes.Labels{ + "lagoon.type": "basic", + "lagoon.service.port": "32a12", + }, + }, + }, + want: ServiceValues{}, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/helpers/helpers.go b/internal/helpers/helpers.go index 001dd977..cd3b031a 100644 --- a/internal/helpers/helpers.go +++ b/internal/helpers/helpers.go @@ -1,9 +1,11 @@ package helpers import ( + "bytes" "crypto/md5" "crypto/sha256" "encoding/base32" + "encoding/gob" "encoding/hex" "fmt" "os" @@ -28,6 +30,11 @@ func IntPtr(i int) *int { return &i } +// Int32Ptr +func Int32Ptr(i int32) *int32 { + return &i +} + // GetMD5HashWithNewLine . // in Lagoon this bash is used to generated the hash, but the `echo "${ROUTE_DOMAIN}"` adds a new line at the end, so the generated // sum has this in it, we need to replicate this here @@ -204,3 +211,11 @@ func CheckLabelLength(labels map[string]string) error { } return nil } + +func DeepCopy(src, dist interface{}) (err error) { + buf := bytes.Buffer{} + if err = gob.NewEncoder(&buf).Encode(src); err != nil { + return + } + return gob.NewDecoder(&buf).Decode(dist) +} diff --git a/internal/templating/backups/template_prebackuppod.go b/internal/templating/backups/template_prebackuppod.go new file mode 100644 index 00000000..0010a7ba --- /dev/null +++ b/internal/templating/backups/template_prebackuppod.go @@ -0,0 +1,392 @@ +package backups + +import ( + "bytes" + "fmt" + "html/template" + "strings" + + "github.com/uselagoon/build-deploy-tool/internal/generator" + "github.com/uselagoon/build-deploy-tool/internal/helpers" + + k8upv1 "github.com/k8up-io/k8up/v2/api/v1" + k8upv1alpha1 "github.com/vshn/k8up/api/v1alpha1" + apivalidation "k8s.io/apimachinery/pkg/api/validation" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metavalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" + + "sigs.k8s.io/yaml" +) + +func GeneratePreBackupPod( + lValues generator.BuildValues, +) ([]byte, error) { + // generate the template spec + + var result []byte + separator := []byte("---\n") + + // add the default labels + labels := map[string]string{ + "app.kubernetes.io/managed-by": "build-deploy-tool", + "lagoon.sh/project": lValues.Project, + "lagoon.sh/environment": lValues.Environment, + "lagoon.sh/environmentType": lValues.EnvironmentType, + "lagoon.sh/buildType": lValues.BuildType, + } + + // add the default annotations + annotations := map[string]string{ + "lagoon.sh/version": lValues.LagoonVersion, + } + + // add any additional labels + additionalLabels := map[string]string{} + additionalAnnotations := map[string]string{} + if lValues.BuildType == "branch" { + additionalAnnotations["lagoon.sh/branch"] = lValues.Branch + } else if lValues.BuildType == "pullrequest" { + additionalAnnotations["lagoon.sh/prNumber"] = lValues.PRNumber + additionalAnnotations["lagoon.sh/prHeadBranch"] = lValues.PRHeadBranch + additionalAnnotations["lagoon.sh/prBaseBranch"] = lValues.PRBaseBranch + + } + + // create the prebackuppods + for _, serviceValues := range lValues.Services { + if _, ok := preBackupPodSpecs[serviceValues.Type]; ok { + switch lValues.Backup.K8upVersion { + case "v1": + prebackuppod := &k8upv1alpha1.PreBackupPod{ + TypeMeta: metav1.TypeMeta{ + Kind: "PreBackupPod", + APIVersion: k8upv1alpha1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-prebackuppod", serviceValues.Name), + }, + Spec: k8upv1alpha1.PreBackupPodSpec{}, + } + + prebackuppod.ObjectMeta.Labels = labels + prebackuppod.ObjectMeta.Annotations = annotations + + var pbp bytes.Buffer + tmpl, _ := template.New("").Funcs(funcMap).Parse(preBackupPodSpecs[serviceValues.Type]) + err := tmpl.Execute(&pbp, serviceValues) + if err != nil { + return nil, err + } + k8upPBPSpec := k8upv1alpha1.PreBackupPodSpec{} + err = yaml.Unmarshal(pbp.Bytes(), &k8upPBPSpec) + if err != nil { + return nil, err + } + k8upPBPSpec.Pod.ObjectMeta.Labels = make(map[string]string) + k8upPBPSpec.Pod.ObjectMeta.Labels = labels + k8upPBPSpec.Pod.ObjectMeta.Labels["prebackuppod"] = serviceValues.Name + prebackuppod.Spec = k8upPBPSpec + + for key, value := range additionalLabels { + prebackuppod.ObjectMeta.Labels[key] = value + } + // add any additional annotations + for key, value := range additionalAnnotations { + prebackuppod.ObjectMeta.Annotations[key] = value + } + // validate any annotations + if err := apivalidation.ValidateAnnotations(prebackuppod.ObjectMeta.Annotations, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the annotations for %s/%s are not valid: %v", "prebackuppod", serviceValues.Name, err) + } + } + // validate any labels + if err := metavalidation.ValidateLabels(prebackuppod.ObjectMeta.Labels, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the labels for %s/%s are not valid: %v", "prebackuppod", serviceValues.Name, err) + } + } + + // check length of labels + err = helpers.CheckLabelLength(prebackuppod.ObjectMeta.Labels) + if err != nil { + return nil, err + } + // @TODO: we should review this in the future when we stop doing `kubectl apply` in the builds :) + // marshal the resulting ingress + prebackuppodBytes, err := yaml.Marshal(prebackuppod) + if err != nil { + return nil, err + } + // add the seperator to the template so that it can be `kubectl apply` in bulk as part + // of the current build process + restoreResult := append(separator[:], prebackuppodBytes[:]...) + result = append(result, restoreResult[:]...) + case "v2": + prebackuppod := &k8upv1.PreBackupPod{ + TypeMeta: metav1.TypeMeta{ + Kind: "PreBackupPod", + APIVersion: k8upv1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: serviceValues.Name, + }, + Spec: k8upv1.PreBackupPodSpec{}, + } + + prebackuppod.ObjectMeta.Labels = labels + prebackuppod.ObjectMeta.Annotations = annotations + + var pbp bytes.Buffer + tmpl, _ := template.New("").Funcs(funcMap).Parse(preBackupPodSpecs[serviceValues.Type]) + err := tmpl.Execute(&pbp, serviceValues) + if err != nil { + return nil, err + } + k8upPBPSpec := k8upv1.PreBackupPodSpec{} + err = yaml.Unmarshal(pbp.Bytes(), &k8upPBPSpec) + if err != nil { + return nil, err + } + k8upPBPSpec.Pod.ObjectMeta.Labels = make(map[string]string) + k8upPBPSpec.Pod.ObjectMeta.Labels = labels + k8upPBPSpec.Pod.ObjectMeta.Labels["prebackuppod"] = serviceValues.Name + prebackuppod.Spec = k8upPBPSpec + + for key, value := range additionalLabels { + prebackuppod.ObjectMeta.Labels[key] = value + } + // add any additional annotations + for key, value := range additionalAnnotations { + prebackuppod.ObjectMeta.Annotations[key] = value + } + // validate any annotations + if err := apivalidation.ValidateAnnotations(prebackuppod.ObjectMeta.Annotations, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the annotations for %s/%s are not valid: %v", "prebackuppod", serviceValues.Name, err) + } + } + // validate any labels + if err := metavalidation.ValidateLabels(prebackuppod.ObjectMeta.Labels, nil); err != nil { + if len(err) != 0 { + return nil, fmt.Errorf("the labels for %s/%s are not valid: %v", "prebackuppod", serviceValues.Name, err) + } + } + + // check length of labels + err = helpers.CheckLabelLength(prebackuppod.ObjectMeta.Labels) + if err != nil { + return nil, err + } + // @TODO: we should review this in the future when we stop doing `kubectl apply` in the builds :) + // marshal the resulting ingress + prebackuppodBytes, err := yaml.Marshal(prebackuppod) + if err != nil { + return nil, err + } + // add the seperator to the template so that it can be `kubectl apply` in bulk as part + // of the current build process + restoreResult := append(separator[:], prebackuppodBytes[:]...) + result = append(result, restoreResult[:]...) + } + } + } + return result, nil +} + +var funcMap = template.FuncMap{ + "VarFix": varFix, +} + +// varfix just uppercases and replaces - with _ for variable names +func varFix(s string) string { + return fmt.Sprintf("%s", strings.ToUpper(strings.Replace(s, "-", "_", -1))) +} + +// this is just the first run at doing this, once the service template generator is introduced, this will need to be re-evaluated +type PreBackupPods map[string]string + +// this is just the first run at doing this, once the service template generator is introduced, this will need to be re-evaluated +var preBackupPodSpecs = PreBackupPods{ + "mariadb-dbaas": `backupCommand: |- + /bin/sh -c "dump=$(mktemp) + && mysqldump --max-allowed-packet=500M --events --routines --quick + --add-locks --no-autocommit --single-transaction --no-create-db + --no-data --no-tablespaces + -h $BACKUP_DB_HOST + -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE + > $dump + && mysqldump --max-allowed-packet=500M --events --routines --quick + --add-locks --no-autocommit --single-transaction --no-create-db + --ignore-table=$BACKUP_DB_DATABASE.watchdog + --no-create-info --no-tablespaces + -h $BACKUP_DB_HOST + -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE + >> $dump + && cat $dump && rm $dump" +fileExtension: .{{ .Name }}.sql +pod: + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/amazeeio/alpine-mysql-client + imagePullPolicy: Always + name: {{ .Name }}-prebackuppod`, + "postgres-dbaas": `backupCommand: /bin/sh -c "PGPASSWORD=$BACKUP_DB_PASSWORD pg_dump --host=$BACKUP_DB_HOST --port=$BACKUP_DB_PORT --dbname=$BACKUP_DB_NAME --username=$BACKUP_DB_USERNAME --format=t -w" +fileExtension: .{{ .Name }}.tar +pod: + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/uselagoon/php-8.0-cli + imagePullPolicy: Always + name: {{ .Name }}-prebackuppod`, + "mongodb-dbaas": `backupCommand: /bin/sh -c "mongodump --uri=mongodb://${BACKUP_DB_USER}:${BACKUP_DB_PASSWORD}@${BACKUP_DB_HOST}:${BACKUP_DB_PORT}/${BACKUP_DB_NAME}?ssl=true&sslInsecure=true&tls=true&tlsInsecure=true --archive" +fileExtension: .{{ .Name }}.bson +pod: + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: {{ .Name | VarFix }}_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/uselagoon/php-8.0-cli + imagePullPolicy: Always + name: {{ .Name }}-prebackuppod`, + "elasticsearch": `backupCommand: /bin/sh -c "tar -cf - -C {{ .PersistentVolumePath }} ." +fileExtension: .{{ .Name }}.tar +pod: + spec: + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: lagoon.sh/service + operator: In + values: + - {{ .Name }} + topologyKey: kubernetes.io/hostname + weight: 100 + containers: + - args: + - sleep + - infinity + envFrom: + - configMapRef: + name: lagoon-env + image: imagecache.amazeeio.cloud/library/alpine + imagePullPolicy: Always + name: {{ .Name }}-prebackuppod + volumeMounts: + - name: {{ .PersistentVolumeName }} + mountPath: "{{ .PersistentVolumePath }}" + volumes: + - name: {{ .PersistentVolumeName }} + persistentVolumeClaim: + claimName: {{ .PersistentVolumeName }}`, + "opensearch": `backupCommand: /bin/sh -c "tar -cf - -C {{ .PersistentVolumePath }} ." +fileExtension: .{{ .Name }}.tar +pod: + spec: + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: lagoon.sh/service + operator: In + values: + - {{ .Name }} + topologyKey: kubernetes.io/hostname + weight: 100 + containers: + - args: + - sleep + - infinity + envFrom: + - configMapRef: + name: lagoon-env + image: imagecache.amazeeio.cloud/library/alpine + imagePullPolicy: Always + name: {{ .Name }}-prebackuppod + volumeMounts: + - name: {{ .PersistentVolumeName }} + mountPath: "{{ .PersistentVolumePath }}" + volumes: + - name: {{ .PersistentVolumeName }} + persistentVolumeClaim: + claimName: {{ .PersistentVolumeName }}`, +} diff --git a/internal/templating/backups/template_prebackuppod_test.go b/internal/templating/backups/template_prebackuppod_test.go new file mode 100644 index 00000000..3e8a2188 --- /dev/null +++ b/internal/templating/backups/template_prebackuppod_test.go @@ -0,0 +1,213 @@ +package backups + +import ( + "os" + "reflect" + "testing" + "time" + + "github.com/uselagoon/build-deploy-tool/internal/dbaasclient" + "github.com/uselagoon/build-deploy-tool/internal/generator" +) + +func TestGeneratePreBackupPod(t *testing.T) { + type args struct { + lValues generator.BuildValues + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "test1 - k8up/v1alpha1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Services: []generator.ServiceValues{ + { + Name: "mariadb-database", + OverrideName: "mariadb-database", + Type: "mariadb-dbaas", + DBaaSEnvironment: "development", + }, + }, + Backup: generator.BackupConfiguration{ + K8upVersion: "v1", + }, + }, + }, + want: "test-resources/result-prebackuppod1.yaml", + }, + { + name: "test2 - k8up/v1alpha1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Services: []generator.ServiceValues{ + { + Name: "postgres-database", + OverrideName: "postgres-database", + Type: "postgres-dbaas", + DBaaSEnvironment: "development", + }, + }, + Backup: generator.BackupConfiguration{ + K8upVersion: "v1", + }, + }, + }, + want: "test-resources/result-prebackuppod2.yaml", + }, + { + name: "test3 - k8up/v1alpha1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Services: []generator.ServiceValues{ + { + Name: "mongodb-database", + OverrideName: "mongodb-database", + Type: "mongodb-dbaas", + DBaaSEnvironment: "development", + }, + }, + Backup: generator.BackupConfiguration{ + K8upVersion: "v1", + }, + }, + }, + want: "test-resources/result-prebackuppod3.yaml", + }, + { + name: "test4 - k8up/v1alpha1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Services: []generator.ServiceValues{ + { + Name: "elasticsearch", + OverrideName: "elasticsearch", + Type: "elasticsearch", + DBaaSEnvironment: "development", + PersistentVolumeName: "elastic", + PersistentVolumePath: "/var/storage/path", + }, + }, + Backup: generator.BackupConfiguration{ + K8upVersion: "v1", + }, + }, + }, + want: "test-resources/result-prebackuppod4.yaml", + }, + { + name: "test5 - k8up/v1alpha1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Services: []generator.ServiceValues{ + { + Name: "opensearch", + OverrideName: "opensearch", + Type: "opensearch", + DBaaSEnvironment: "development", + PersistentVolumeName: "elastic", + PersistentVolumePath: "/var/storage/path", + }, + }, + Backup: generator.BackupConfiguration{ + K8upVersion: "v1", + }, + }, + }, + want: "test-resources/result-prebackuppod5.yaml", + }, + { + name: "test6 - k8up/v1", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-with-really-really-reall-3fdb", + EnvironmentType: "production", + Namespace: "myexample-project-environment-with-really-really-reall-3fdb", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-with-really-really-reall-3fdb", + Services: []generator.ServiceValues{ + { + Name: "opensearch", + OverrideName: "opensearch", + Type: "opensearch", + DBaaSEnvironment: "development", + PersistentVolumeName: "elastic", + PersistentVolumePath: "/var/storage/path", + }, + }, + Backup: generator.BackupConfiguration{ + K8upVersion: "v2", + }, + }, + }, + want: "test-resources/result-prebackuppod6.yaml", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // add dbaasclient overrides for tests + tt.args.lValues.DBaaSClient = dbaasclient.NewClient(dbaasclient.Client{ + RetryMax: 5, + RetryWaitMin: time.Duration(10) * time.Millisecond, + RetryWaitMax: time.Duration(50) * time.Millisecond, + }) + got, err := GeneratePreBackupPod(tt.args.lValues) + if err != nil { + t.Errorf("couldn't generate template %v: %v", tt.want, err) + } + r1, err := os.ReadFile(tt.want) + if err != nil { + t.Errorf("couldn't read file %v: %v", tt.want, err) + } + if !reflect.DeepEqual(string(got), string(r1)) { + t.Errorf("GeneratePreBackupPod() = %v, want %v", string(got), string(r1)) + } + }) + } +} diff --git a/internal/templating/backups/test-resources/result-prebackuppod1.yaml b/internal/templating/backups/test-resources/result-prebackuppod1.yaml new file mode 100644 index 00000000..2a93f139 --- /dev/null +++ b/internal/templating/backups/test-resources/result-prebackuppod1.yaml @@ -0,0 +1,78 @@ +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: mariadb-database + name: mariadb-database-prebackuppod +spec: + backupCommand: |- + /bin/sh -c "dump=$(mktemp) + && mysqldump --max-allowed-packet=500M --events --routines --quick + --add-locks --no-autocommit --single-transaction --no-create-db + --no-data --no-tablespaces + -h $BACKUP_DB_HOST + -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE + > $dump + && mysqldump --max-allowed-packet=500M --events --routines --quick + --add-locks --no-autocommit --single-transaction --no-create-db + --ignore-table=$BACKUP_DB_DATABASE.watchdog + --no-create-info --no-tablespaces + -h $BACKUP_DB_HOST + -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE + >> $dump + && cat $dump && rm $dump" + fileExtension: .mariadb-database.sql + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: mariadb-database + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: MARIADB_DATABASE_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: MARIADB_DATABASE_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: MARIADB_DATABASE_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: MARIADB_DATABASE_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/amazeeio/alpine-mysql-client + imagePullPolicy: Always + name: mariadb-database-prebackuppod + resources: {} diff --git a/internal/templating/backups/test-resources/result-prebackuppod2.yaml b/internal/templating/backups/test-resources/result-prebackuppod2.yaml new file mode 100644 index 00000000..9b898d1a --- /dev/null +++ b/internal/templating/backups/test-resources/result-prebackuppod2.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: postgres-database + name: postgres-database-prebackuppod +spec: + backupCommand: /bin/sh -c "PGPASSWORD=$BACKUP_DB_PASSWORD pg_dump --host=$BACKUP_DB_HOST + --port=$BACKUP_DB_PORT --dbname=$BACKUP_DB_NAME --username=$BACKUP_DB_USERNAME + --format=t -w" + fileExtension: .postgres-database.tar + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: postgres-database + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: POSTGRES_DATABASE_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: POSTGRES_DATABASE_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: POSTGRES_DATABASE_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: POSTGRES_DATABASE_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/uselagoon/php-8.0-cli + imagePullPolicy: Always + name: postgres-database-prebackuppod + resources: {} diff --git a/internal/templating/backups/test-resources/result-prebackuppod3.yaml b/internal/templating/backups/test-resources/result-prebackuppod3.yaml new file mode 100644 index 00000000..d64bad9c --- /dev/null +++ b/internal/templating/backups/test-resources/result-prebackuppod3.yaml @@ -0,0 +1,60 @@ +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: mongodb-database + name: mongodb-database-prebackuppod +spec: + backupCommand: /bin/sh -c "mongodump --uri=mongodb://${BACKUP_DB_USER}:${BACKUP_DB_PASSWORD}@${BACKUP_DB_HOST}:${BACKUP_DB_PORT}/${BACKUP_DB_NAME}?ssl=true&sslInsecure=true&tls=true&tlsInsecure=true + --archive" + fileExtension: .mongodb-database.bson + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: mongodb-database + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: MONGODB_DATABASE_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: MONGODB_DATABASE_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: MONGODB_DATABASE_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: MONGODB_DATABASE_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/uselagoon/php-8.0-cli + imagePullPolicy: Always + name: mongodb-database-prebackuppod + resources: {} diff --git a/internal/templating/backups/test-resources/result-prebackuppod4.yaml b/internal/templating/backups/test-resources/result-prebackuppod4.yaml new file mode 100644 index 00000000..85e41228 --- /dev/null +++ b/internal/templating/backups/test-resources/result-prebackuppod4.yaml @@ -0,0 +1,48 @@ +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: elasticsearch + name: elasticsearch-prebackuppod +spec: + backupCommand: /bin/sh -c "tar -cf - -C /var/storage/path ." + fileExtension: .elasticsearch.tar + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: elasticsearch + spec: + containers: + - args: + - sleep + - infinity + envFrom: + - configMapRef: + name: lagoon-env + image: imagecache.amazeeio.cloud/library/alpine + imagePullPolicy: Always + name: elasticsearch-prebackuppod + resources: {} + volumeMounts: + - mountPath: /var/storage/path + name: elastic + volumes: + - name: elastic + persistentVolumeClaim: + claimName: elastic diff --git a/internal/templating/backups/test-resources/result-prebackuppod5.yaml b/internal/templating/backups/test-resources/result-prebackuppod5.yaml new file mode 100644 index 00000000..70c4b228 --- /dev/null +++ b/internal/templating/backups/test-resources/result-prebackuppod5.yaml @@ -0,0 +1,48 @@ +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: opensearch + name: opensearch-prebackuppod +spec: + backupCommand: /bin/sh -c "tar -cf - -C /var/storage/path ." + fileExtension: .opensearch.tar + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: opensearch + spec: + containers: + - args: + - sleep + - infinity + envFrom: + - configMapRef: + name: lagoon-env + image: imagecache.amazeeio.cloud/library/alpine + imagePullPolicy: Always + name: opensearch-prebackuppod + resources: {} + volumeMounts: + - mountPath: /var/storage/path + name: elastic + volumes: + - name: elastic + persistentVolumeClaim: + claimName: elastic diff --git a/internal/templating/backups/test-resources/result-prebackuppod6.yaml b/internal/templating/backups/test-resources/result-prebackuppod6.yaml new file mode 100644 index 00000000..2046026e --- /dev/null +++ b/internal/templating/backups/test-resources/result-prebackuppod6.yaml @@ -0,0 +1,48 @@ +--- +apiVersion: k8up.io/v1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: environment-with-really-really-reall-3fdb + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: opensearch + name: opensearch +spec: + backupCommand: /bin/sh -c "tar -cf - -C /var/storage/path ." + fileExtension: .opensearch.tar + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-with-really-really-reall-3fdb + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: opensearch + spec: + containers: + - args: + - sleep + - infinity + envFrom: + - configMapRef: + name: lagoon-env + image: imagecache.amazeeio.cloud/library/alpine + imagePullPolicy: Always + name: opensearch-prebackuppod + resources: {} + volumeMounts: + - mountPath: /var/storage/path + name: elastic + volumes: + - name: elastic + persistentVolumeClaim: + claimName: elastic diff --git a/legacy/helmcharts/elasticsearch/templates/prebackuppod.yaml b/legacy/helmcharts/elasticsearch/templates/prebackuppod.yaml deleted file mode 100644 index c2b90366..00000000 --- a/legacy/helmcharts/elasticsearch/templates/prebackuppod.yaml +++ /dev/null @@ -1,48 +0,0 @@ -{{ if .Capabilities.APIVersions.Has "backup.appuio.ch/v1alpha1/PreBackupPod" }} -apiVersion: backup.appuio.ch/v1alpha1 -kind: PreBackupPod -metadata: - name: {{ include "elasticsearch.fullname" . }}-prebackuppod - labels: - {{- include "elasticsearch.labels" . | nindent 4 }} - annotations: - {{- include "elasticsearch.annotations" . | nindent 4 }} -spec: - backupCommand: /bin/sh -c "tar -cf - -C {{ .Values.persistentStorage.path }} ." - fileExtension: .{{ include "elasticsearch.fullname" . }}.tar - pod: - metadata: - labels: - prebackuppod: {{ include "elasticsearch.fullname" . }} - {{- include "elasticsearch.labels" . | nindent 8 }} - spec: - affinity: - podAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: - matchExpressions: - - key: lagoon.sh/service - operator: In - values: - - {{ include "elasticsearch.fullname" . }} - topologyKey: kubernetes.io/hostname - weight: 100 - containers: - - args: - - sleep - - infinity - envFrom: - - configMapRef: - name: lagoon-env - image: imagecache.amazeeio.cloud/library/alpine - imagePullPolicy: Always - name: {{ include "elasticsearch.fullname" . }}-prebackuppod - volumeMounts: - - name: {{ include "elasticsearch.persistentStorageName" . }} - mountPath: {{ .Values.persistentStorage.path | quote }} - volumes: - - name: {{ include "elasticsearch.persistentStorageName" . }} - persistentVolumeClaim: - claimName: {{ include "elasticsearch.persistentStorageName" . }} -{{ end }} diff --git a/legacy/helmcharts/mariadb-dbaas/templates/prebackuppod.yaml b/legacy/helmcharts/mariadb-dbaas/templates/prebackuppod.yaml deleted file mode 100644 index b661222b..00000000 --- a/legacy/helmcharts/mariadb-dbaas/templates/prebackuppod.yaml +++ /dev/null @@ -1,66 +0,0 @@ -{{ if .Capabilities.APIVersions.Has "backup.appuio.ch/v1alpha1/PreBackupPod" }} -apiVersion: backup.appuio.ch/v1alpha1 -kind: PreBackupPod -metadata: - name: {{ include "mariadb-dbaas.fullname" . }}-prebackuppod - labels: - {{- include "mariadb-dbaas.labels" . | nindent 4 }} - annotations: - {{- include "mariadb-dbaas.annotations" . | nindent 4 }} -spec: - backupCommand: >- - /bin/sh -c "dump=$(mktemp) - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --no-data --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - > $dump - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --ignore-table=$BACKUP_DB_DATABASE.watchdog - --no-create-info --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - >> $dump - && cat $dump && rm $dump" - fileExtension: .{{ include "mariadb-dbaas.fullname" . }}.sql - pod: - metadata: - labels: - prebackuppod: {{ include "mariadb-dbaas.fullname" . }} - {{- include "mariadb-dbaas.labels" . | nindent 8 }} - spec: - containers: - - args: - - sleep - - infinity - env: - - name: BACKUP_DB_HOST - valueFrom: - configMapKeyRef: - key: {{ include "mariadb-dbaas.fullnameUppercase" . }}_HOST - name: lagoon-env - - name: BACKUP_DB_USERNAME - valueFrom: - configMapKeyRef: - key: {{ include "mariadb-dbaas.fullnameUppercase" . }}_USERNAME - name: lagoon-env - - name: BACKUP_DB_PASSWORD - valueFrom: - configMapKeyRef: - key: {{ include "mariadb-dbaas.fullnameUppercase" . }}_PASSWORD - name: lagoon-env - - name: BACKUP_DB_DATABASE - valueFrom: - configMapKeyRef: - key: {{ include "mariadb-dbaas.fullnameUppercase" . }}_DATABASE - name: lagoon-env - image: imagecache.amazeeio.cloud/amazeeio/alpine-mysql-client - imagePullPolicy: Always - name: {{ include "mariadb-dbaas.fullname" . }}-prebackuppod -{{ end }} diff --git a/legacy/helmcharts/mongodb-dbaas/templates/prebackuppod.yaml b/legacy/helmcharts/mongodb-dbaas/templates/prebackuppod.yaml deleted file mode 100644 index 4f893420..00000000 --- a/legacy/helmcharts/mongodb-dbaas/templates/prebackuppod.yaml +++ /dev/null @@ -1,67 +0,0 @@ -{{ if .Capabilities.APIVersions.Has "backup.appuio.ch/v1alpha1/PreBackupPod" }} -apiVersion: backup.appuio.ch/v1alpha1 -kind: PreBackupPod -metadata: - name: {{ include "mongodb-dbaas.fullname" . }}-prebackuppod - labels: - {{- include "mongodb-dbaas.labels" . | nindent 4 }} - annotations: - {{- include "mongodb-dbaas.annotations" . | nindent 4 }} -spec: - backupCommand: /bin/sh -c "mongodump --uri=mongodb://${BACKUP_DB_USER}:${BACKUP_DB_PASSWORD}@${BACKUP_DB_HOST}:${BACKUP_DB_PORT}/${BACKUP_DB_NAME}?ssl=true&sslInsecure=true&tls=true&tlsInsecure=true --archive" - fileExtension: .{{ include "mongodb-dbaas.fullname" . }}.bson - pod: - metadata: - labels: - prebackuppod: {{ include "mongodb-dbaas.fullname" . }} - {{- include "mongodb-dbaas.labels" . | nindent 8 }} - spec: - containers: - - args: - - sleep - - infinity - env: - - name: BACKUP_DB_HOST - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_HOST - name: lagoon-env - - name: BACKUP_DB_USER - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_USER - name: lagoon-env - - name: BACKUP_DB_PASSWORD - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_PASSWORD - name: lagoon-env - - name: BACKUP_DB_NAME - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_DB_NAME - name: lagoon-env - - name: BACKUP_DB_PORT - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_DB_PORT - name: lagoon-env - - name: BACKUP_DB_AUTHSOURCE - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_DB_AUTHSOURCE - name: lagoon-env - - name: BACKUP_DB_AUTHMECHANISM - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_DB_AUTHMECHANISM - name: lagoon-env - - name: BACKUP_DB_AUTHTLS - valueFrom: - configMapKeyRef: - key: {{ include "mongodb-dbaas.fullnameUppercase" . }}_DB_AUTHTLS - name: lagoon-env - image: imagecache.amazeeio.cloud/uselagoon/php-8.0-cli - imagePullPolicy: Always - name: {{ include "mongodb-dbaas.fullname" . }}-prebackuppod -{{ end }} diff --git a/legacy/helmcharts/opensearch/templates/prebackuppod.yaml b/legacy/helmcharts/opensearch/templates/prebackuppod.yaml deleted file mode 100644 index 7080fdec..00000000 --- a/legacy/helmcharts/opensearch/templates/prebackuppod.yaml +++ /dev/null @@ -1,48 +0,0 @@ -{{ if .Capabilities.APIVersions.Has "backup.appuio.ch/v1alpha1/PreBackupPod" }} -apiVersion: backup.appuio.ch/v1alpha1 -kind: PreBackupPod -metadata: - name: {{ include "opensearch.fullname" . }}-prebackuppod - labels: - {{- include "opensearch.labels" . | nindent 4 }} - annotations: - {{- include "opensearch.annotations" . | nindent 4 }} -spec: - backupCommand: /bin/sh -c "tar -cf - -C {{ .Values.persistentStorage.path }} ." - fileExtension: .{{ include "opensearch.fullname" . }}.tar - pod: - metadata: - labels: - prebackuppod: {{ include "opensearch.fullname" . }} - {{- include "opensearch.labels" . | nindent 8 }} - spec: - affinity: - podAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: - matchExpressions: - - key: lagoon.sh/service - operator: In - values: - - {{ include "opensearch.fullname" . }} - topologyKey: kubernetes.io/hostname - weight: 100 - containers: - - args: - - sleep - - infinity - envFrom: - - configMapRef: - name: lagoon-env - image: imagecache.amazeeio.cloud/library/alpine - imagePullPolicy: Always - name: {{ include "opensearch.fullname" . }}-prebackuppod - volumeMounts: - - name: {{ include "opensearch.persistentStorageName" . }} - mountPath: {{ .Values.persistentStorage.path | quote }} - volumes: - - name: {{ include "opensearch.persistentStorageName" . }} - persistentVolumeClaim: - claimName: {{ include "opensearch.persistentStorageName" . }} -{{ end }} diff --git a/legacy/helmcharts/postgres-dbaas/templates/prebackuppod.yaml b/legacy/helmcharts/postgres-dbaas/templates/prebackuppod.yaml deleted file mode 100644 index 1e648f42..00000000 --- a/legacy/helmcharts/postgres-dbaas/templates/prebackuppod.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{ if .Capabilities.APIVersions.Has "backup.appuio.ch/v1alpha1/PreBackupPod" }} -apiVersion: backup.appuio.ch/v1alpha1 -kind: PreBackupPod -metadata: - name: {{ include "postgres-dbaas.fullname" . }}-prebackuppod - labels: - {{- include "postgres-dbaas.labels" . | nindent 4 }} - annotations: - {{- include "postgres-dbaas.annotations" . | nindent 4 }} -spec: - backupCommand: /bin/sh -c "PGPASSWORD=$BACKUP_DB_PASSWORD pg_dump --host=$BACKUP_DB_HOST --port=$BACKUP_DB_PORT --dbname=$BACKUP_DB_NAME --username=$BACKUP_DB_USERNAME --format=t -w" - fileExtension: .{{ include "postgres-dbaas.fullname" . }}.tar - pod: - metadata: - labels: - prebackuppod: {{ include "postgres-dbaas.fullname" . }} - {{- include "postgres-dbaas.labels" . | nindent 8 }} - spec: - containers: - - args: - - sleep - - infinity - env: - - name: BACKUP_DB_HOST - valueFrom: - configMapKeyRef: - key: {{ include "postgres-dbaas.fullnameUppercase" . }}_HOST - name: lagoon-env - - name: BACKUP_DB_PORT - valueFrom: - configMapKeyRef: - key: {{ include "postgres-dbaas.fullnameUppercase" . }}_PORT - name: lagoon-env - - name: BACKUP_DB_USERNAME - valueFrom: - configMapKeyRef: - key: {{ include "postgres-dbaas.fullnameUppercase" . }}_USERNAME - name: lagoon-env - - name: BACKUP_DB_PASSWORD - valueFrom: - configMapKeyRef: - key: {{ include "postgres-dbaas.fullnameUppercase" . }}_PASSWORD - name: lagoon-env - - name: BACKUP_DB_NAME - valueFrom: - configMapKeyRef: - key: {{ include "postgres-dbaas.fullnameUppercase" . }}_DATABASE - name: lagoon-env - image: imagecache.amazeeio.cloud/uselagoon/php-8.0-cli - imagePullPolicy: Always - name: {{ include "postgres-dbaas.fullname" . }}-prebackuppod -{{ end }} diff --git a/test-resources/template-backups/test1-results/prebackuppods.yaml b/test-resources/template-backups/test1-results/prebackuppods.yaml new file mode 100644 index 00000000..a33f4070 --- /dev/null +++ b/test-resources/template-backups/test1-results/prebackuppods.yaml @@ -0,0 +1,126 @@ +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: mariadb + name: mariadb-prebackuppod +spec: + backupCommand: |- + /bin/sh -c "dump=$(mktemp) + && mysqldump --max-allowed-packet=500M --events --routines --quick + --add-locks --no-autocommit --single-transaction --no-create-db + --no-data --no-tablespaces + -h $BACKUP_DB_HOST + -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE + > $dump + && mysqldump --max-allowed-packet=500M --events --routines --quick + --add-locks --no-autocommit --single-transaction --no-create-db + --ignore-table=$BACKUP_DB_DATABASE.watchdog + --no-create-info --no-tablespaces + -h $BACKUP_DB_HOST + -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE + >> $dump + && cat $dump && rm $dump" + fileExtension: .mariadb.sql + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: mariadb + spec: + containers: + - args: + - sleep + - infinity + env: + - name: BACKUP_DB_HOST + valueFrom: + configMapKeyRef: + key: MARIADB_HOST + name: lagoon-env + - name: BACKUP_DB_USERNAME + valueFrom: + configMapKeyRef: + key: MARIADB_USERNAME + name: lagoon-env + - name: BACKUP_DB_PASSWORD + valueFrom: + configMapKeyRef: + key: MARIADB_PASSWORD + name: lagoon-env + - name: BACKUP_DB_DATABASE + valueFrom: + configMapKeyRef: + key: MARIADB_DATABASE + name: lagoon-env + image: imagecache.amazeeio.cloud/amazeeio/alpine-mysql-client + imagePullPolicy: Always + name: mariadb-prebackuppod + resources: {} +--- +apiVersion: backup.appuio.ch/v1alpha1 +kind: PreBackupPod +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: elasticsearch + name: elasticsearch-prebackuppod +spec: + backupCommand: /bin/sh -c "tar -cf - -C /usr/share/elasticsearch/data ." + fileExtension: .elasticsearch.tar + pod: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + prebackuppod: elasticsearch + spec: + containers: + - args: + - sleep + - infinity + envFrom: + - configMapRef: + name: lagoon-env + image: imagecache.amazeeio.cloud/library/alpine + imagePullPolicy: Always + name: elasticsearch-prebackuppod + resources: {} + volumeMounts: + - mountPath: /usr/share/elasticsearch/data + name: elasticsearch + volumes: + - name: elasticsearch + persistentVolumeClaim: + claimName: elasticsearch diff --git a/test-resources/template-backups/test1/docker-compose.yml b/test-resources/template-backups/test1/docker-compose.yml index 85386270..e116c1d3 100644 --- a/test-resources/template-backups/test1/docker-compose.yml +++ b/test-resources/template-backups/test1/docker-compose.yml @@ -15,6 +15,28 @@ services: - LAGOON_LOCALDEV_HTTP_PORT=3000 - LAGOON_ROUTE=http://node.docker.amazee.io + mariadb: + image: uselagoon/mariadb-10.5-drupal:latest + labels: + lagoon.type: mariadb + lando.type: mariadb-drupal + ports: + - "3306" # exposes the port 3306 with a random local port, find it with `docker-compose port mariadb 3306` + + elasticsearch: + image: uselagoon/elasticsearch-7:latest + labels: + lagoon.type: elasticsearch + lando.type: elasticsearch + ports: + - "9200" # exposes the port 9200 with a random local port, find it with `docker-compose port elasticsearch 9200` + volumes: + - search:/usr/share/elasticsearch/data + networks: amazeeio-network: - external: true \ No newline at end of file + external: true + +volumes: + search: + {} \ No newline at end of file diff --git a/test-resources/template-backups/test2-results/prebackuppods.yaml b/test-resources/template-backups/test2-results/prebackuppods.yaml new file mode 100644 index 00000000..e69de29b diff --git a/test-resources/template-backups/test3-results/prebackuppods.yaml b/test-resources/template-backups/test3-results/prebackuppods.yaml new file mode 100644 index 00000000..e69de29b diff --git a/test-resources/template-backups/test4-results/prebackuppods.yaml b/test-resources/template-backups/test4-results/prebackuppods.yaml new file mode 100644 index 00000000..e69de29b diff --git a/test-resources/template-backups/test5-results/prebackuppods.yaml b/test-resources/template-backups/test5-results/prebackuppods.yaml new file mode 100644 index 00000000..e69de29b diff --git a/test-resources/template-backups/test6-results/prebackuppods.yaml b/test-resources/template-backups/test6-results/prebackuppods.yaml new file mode 100644 index 00000000..e69de29b From b627ce3b3a99568824dfe2268ab916ab367a6a84 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Fri, 2 Dec 2022 16:13:27 +1100 Subject: [PATCH 11/17] chore: remove creationtimestamp from podspecs --- .../backups/template_prebackuppod.go | 30 +++++++++++++++---- .../test-resources/result-prebackuppod1.yaml | 1 - .../test-resources/result-prebackuppod2.yaml | 1 - .../test-resources/result-prebackuppod3.yaml | 1 - .../test-resources/result-prebackuppod4.yaml | 1 - .../test-resources/result-prebackuppod5.yaml | 1 - .../test-resources/result-prebackuppod6.yaml | 1 - .../test1-results/prebackuppods.yaml | 2 -- 8 files changed, 24 insertions(+), 14 deletions(-) diff --git a/internal/templating/backups/template_prebackuppod.go b/internal/templating/backups/template_prebackuppod.go index 0010a7ba..2d8f2183 100644 --- a/internal/templating/backups/template_prebackuppod.go +++ b/internal/templating/backups/template_prebackuppod.go @@ -82,8 +82,10 @@ func GeneratePreBackupPod( if err != nil { return nil, err } - k8upPBPSpec.Pod.ObjectMeta.Labels = make(map[string]string) - k8upPBPSpec.Pod.ObjectMeta.Labels = labels + + k8upPBPSpec.Pod.ObjectMeta = metav1.ObjectMeta{ + Labels: labels, + } k8upPBPSpec.Pod.ObjectMeta.Labels["prebackuppod"] = serviceValues.Name prebackuppod.Spec = k8upPBPSpec @@ -118,9 +120,11 @@ func GeneratePreBackupPod( if err != nil { return nil, err } + + pbpBytes, _ := RemoveYAML(prebackuppodBytes) // add the seperator to the template so that it can be `kubectl apply` in bulk as part // of the current build process - restoreResult := append(separator[:], prebackuppodBytes[:]...) + restoreResult := append(separator[:], pbpBytes[:]...) result = append(result, restoreResult[:]...) case "v2": prebackuppod := &k8upv1.PreBackupPod{ @@ -148,8 +152,10 @@ func GeneratePreBackupPod( if err != nil { return nil, err } - k8upPBPSpec.Pod.ObjectMeta.Labels = make(map[string]string) - k8upPBPSpec.Pod.ObjectMeta.Labels = labels + + k8upPBPSpec.Pod.ObjectMeta = metav1.ObjectMeta{ + Labels: labels, + } k8upPBPSpec.Pod.ObjectMeta.Labels["prebackuppod"] = serviceValues.Name prebackuppod.Spec = k8upPBPSpec @@ -184,9 +190,10 @@ func GeneratePreBackupPod( if err != nil { return nil, err } + pbpBytes, _ := RemoveYAML(prebackuppodBytes) // add the seperator to the template so that it can be `kubectl apply` in bulk as part // of the current build process - restoreResult := append(separator[:], prebackuppodBytes[:]...) + restoreResult := append(separator[:], pbpBytes[:]...) result = append(result, restoreResult[:]...) } } @@ -194,6 +201,17 @@ func GeneratePreBackupPod( return result, nil } +func RemoveYAML(a []byte) ([]byte, error) { + tmpMap := map[string]interface{}{} + yaml.Unmarshal(a, &tmpMap) + if _, ok := tmpMap["spec"].(map[string]interface{})["pod"].(map[string]interface{})["metadata"]; ok { + delete(tmpMap["spec"].(map[string]interface{})["pod"].(map[string]interface{})["metadata"].(map[string]interface{}), "creationTimestamp") + b, _ := yaml.Marshal(tmpMap) + return b, nil + } + return a, nil +} + var funcMap = template.FuncMap{ "VarFix": varFix, } diff --git a/internal/templating/backups/test-resources/result-prebackuppod1.yaml b/internal/templating/backups/test-resources/result-prebackuppod1.yaml index 2a93f139..91b6a679 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod1.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod1.yaml @@ -38,7 +38,6 @@ spec: fileExtension: .mariadb-database.sql pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch diff --git a/internal/templating/backups/test-resources/result-prebackuppod2.yaml b/internal/templating/backups/test-resources/result-prebackuppod2.yaml index 9b898d1a..aad73c4f 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod2.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod2.yaml @@ -21,7 +21,6 @@ spec: fileExtension: .postgres-database.tar pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch diff --git a/internal/templating/backups/test-resources/result-prebackuppod3.yaml b/internal/templating/backups/test-resources/result-prebackuppod3.yaml index d64bad9c..734992a9 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod3.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod3.yaml @@ -20,7 +20,6 @@ spec: fileExtension: .mongodb-database.bson pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch diff --git a/internal/templating/backups/test-resources/result-prebackuppod4.yaml b/internal/templating/backups/test-resources/result-prebackuppod4.yaml index 85e41228..90d1bed6 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod4.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod4.yaml @@ -19,7 +19,6 @@ spec: fileExtension: .elasticsearch.tar pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch diff --git a/internal/templating/backups/test-resources/result-prebackuppod5.yaml b/internal/templating/backups/test-resources/result-prebackuppod5.yaml index 70c4b228..9af7f5e9 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod5.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod5.yaml @@ -19,7 +19,6 @@ spec: fileExtension: .opensearch.tar pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch diff --git a/internal/templating/backups/test-resources/result-prebackuppod6.yaml b/internal/templating/backups/test-resources/result-prebackuppod6.yaml index 2046026e..ab5fa64a 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod6.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod6.yaml @@ -19,7 +19,6 @@ spec: fileExtension: .opensearch.tar pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch diff --git a/test-resources/template-backups/test1-results/prebackuppods.yaml b/test-resources/template-backups/test1-results/prebackuppods.yaml index a33f4070..8a1c5283 100644 --- a/test-resources/template-backups/test1-results/prebackuppods.yaml +++ b/test-resources/template-backups/test1-results/prebackuppods.yaml @@ -38,7 +38,6 @@ spec: fileExtension: .mariadb.sql pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch @@ -97,7 +96,6 @@ spec: fileExtension: .elasticsearch.tar pod: metadata: - creationTimestamp: null labels: app.kubernetes.io/managed-by: build-deploy-tool lagoon.sh/buildType: branch From 47c1194462a2cfa5a1a77128b633af25b764addf Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Fri, 2 Dec 2022 16:21:41 +1100 Subject: [PATCH 12/17] chore: delete old prebackup pods if there are any --- internal/templating/backups/template_prebackuppod.go | 4 ++-- .../backups/test-resources/result-prebackuppod6.yaml | 2 +- legacy/build-deploy-docker-compose.sh | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/internal/templating/backups/template_prebackuppod.go b/internal/templating/backups/template_prebackuppod.go index 2d8f2183..f11b78ab 100644 --- a/internal/templating/backups/template_prebackuppod.go +++ b/internal/templating/backups/template_prebackuppod.go @@ -133,7 +133,7 @@ func GeneratePreBackupPod( APIVersion: k8upv1.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ - Name: serviceValues.Name, + Name: fmt.Sprintf("%s-prebackuppod", serviceValues.Name), }, Spec: k8upv1.PreBackupPodSpec{}, } @@ -204,7 +204,7 @@ func GeneratePreBackupPod( func RemoveYAML(a []byte) ([]byte, error) { tmpMap := map[string]interface{}{} yaml.Unmarshal(a, &tmpMap) - if _, ok := tmpMap["spec"].(map[string]interface{})["pod"].(map[string]interface{})["metadata"]; ok { + if _, ok := tmpMap["spec"].(map[string]interface{})["pod"].(map[string]interface{})["metadata"].(map[string]interface{})["creationTimestamp"]; ok { delete(tmpMap["spec"].(map[string]interface{})["pod"].(map[string]interface{})["metadata"].(map[string]interface{}), "creationTimestamp") b, _ := yaml.Marshal(tmpMap) return b, nil diff --git a/internal/templating/backups/test-resources/result-prebackuppod6.yaml b/internal/templating/backups/test-resources/result-prebackuppod6.yaml index ab5fa64a..081d0456 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod6.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod6.yaml @@ -13,7 +13,7 @@ metadata: lagoon.sh/environmentType: production lagoon.sh/project: example-project prebackuppod: opensearch - name: opensearch + name: opensearch-prebackuppod spec: backupCommand: /bin/sh -c "tar -cf - -C /var/storage/path ." fileExtension: .opensearch.tar diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index 55cba61c..a80fa1f0 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -1080,6 +1080,9 @@ if [[ "${CAPABILITIES[@]}" =~ "k8up.io/v1/Schedule" ]]; then if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get schedules.backup.appuio.ch k8up-lagoon-backup-schedule &> /dev/null; then kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete schedules.backup.appuio.ch k8up-lagoon-backup-schedule fi + if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get prebackuppods.backup.appuio.ch &> /dev/null; then + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete prebackuppods.backup.appuio.ch --all + fi fi K8UP_VERSION="v2" fi From 5d3e22fe4ee1b6db869f3a30031e4c5978563214 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Fri, 2 Dec 2022 16:47:38 +1100 Subject: [PATCH 13/17] chore: add note about helper function --- internal/templating/backups/template_prebackuppod.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/templating/backups/template_prebackuppod.go b/internal/templating/backups/template_prebackuppod.go index f11b78ab..f340534a 100644 --- a/internal/templating/backups/template_prebackuppod.go +++ b/internal/templating/backups/template_prebackuppod.go @@ -201,6 +201,7 @@ func GeneratePreBackupPod( return result, nil } +// helper function to remove the creationtimestamp from the prebackuppod pod spec so that kubectl will apply without validation errors func RemoveYAML(a []byte) ([]byte, error) { tmpMap := map[string]interface{}{} yaml.Unmarshal(a, &tmpMap) From dabbe1c180df7acd72abc8c7bdcbf05aecc5e963 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 5 Dec 2022 08:35:08 +1100 Subject: [PATCH 14/17] chore: fix mariadb prebackup command --- .../backups/template_prebackuppod.go | 30 +++++++------------ .../test-resources/result-prebackuppod1.yaml | 27 +++++------------ .../test1-results/prebackuppods.yaml | 27 +++++------------ 3 files changed, 24 insertions(+), 60 deletions(-) diff --git a/internal/templating/backups/template_prebackuppod.go b/internal/templating/backups/template_prebackuppod.go index f340534a..d4f63bae 100644 --- a/internal/templating/backups/template_prebackuppod.go +++ b/internal/templating/backups/template_prebackuppod.go @@ -227,26 +227,16 @@ type PreBackupPods map[string]string // this is just the first run at doing this, once the service template generator is introduced, this will need to be re-evaluated var preBackupPodSpecs = PreBackupPods{ - "mariadb-dbaas": `backupCommand: |- - /bin/sh -c "dump=$(mktemp) - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --no-data --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - > $dump - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --ignore-table=$BACKUP_DB_DATABASE.watchdog - --no-create-info --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - >> $dump - && cat $dump && rm $dump" + "mariadb-dbaas": `backupCommand: >- + /bin/sh -c "dump=$(mktemp) && mysqldump --max-allowed-packet=500M --events + --routines --quick --add-locks --no-autocommit --single-transaction + --no-create-db --no-data -h $BACKUP_DB_HOST -u $BACKUP_DB_USERNAME + -p$BACKUP_DB_PASSWORD $BACKUP_DB_DATABASE > $dump && mysqldump + --max-allowed-packet=500M --events --routines --quick --add-locks + --no-autocommit --single-transaction --no-create-db + --ignore-table=$BACKUP_DB_DATABASE.watchdog --no-create-info -h + $BACKUP_DB_HOST -u $BACKUP_DB_USERNAME -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE >> $dump && cat $dump && rm $dump" fileExtension: .{{ .Name }}.sql pod: spec: diff --git a/internal/templating/backups/test-resources/result-prebackuppod1.yaml b/internal/templating/backups/test-resources/result-prebackuppod1.yaml index 91b6a679..9fd89ea0 100644 --- a/internal/templating/backups/test-resources/result-prebackuppod1.yaml +++ b/internal/templating/backups/test-resources/result-prebackuppod1.yaml @@ -15,26 +15,13 @@ metadata: prebackuppod: mariadb-database name: mariadb-database-prebackuppod spec: - backupCommand: |- - /bin/sh -c "dump=$(mktemp) - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --no-data --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - > $dump - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --ignore-table=$BACKUP_DB_DATABASE.watchdog - --no-create-info --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - >> $dump - && cat $dump && rm $dump" + backupCommand: /bin/sh -c "dump=$(mktemp) && mysqldump --max-allowed-packet=500M + --events --routines --quick --add-locks --no-autocommit --single-transaction --no-create-db + --no-data -h $BACKUP_DB_HOST -u $BACKUP_DB_USERNAME -p$BACKUP_DB_PASSWORD $BACKUP_DB_DATABASE + > $dump && mysqldump --max-allowed-packet=500M --events --routines --quick --add-locks + --no-autocommit --single-transaction --no-create-db --ignore-table=$BACKUP_DB_DATABASE.watchdog + --no-create-info -h $BACKUP_DB_HOST -u $BACKUP_DB_USERNAME -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE >> $dump && cat $dump && rm $dump" fileExtension: .mariadb-database.sql pod: metadata: diff --git a/test-resources/template-backups/test1-results/prebackuppods.yaml b/test-resources/template-backups/test1-results/prebackuppods.yaml index 8a1c5283..0f75b8ed 100644 --- a/test-resources/template-backups/test1-results/prebackuppods.yaml +++ b/test-resources/template-backups/test1-results/prebackuppods.yaml @@ -15,26 +15,13 @@ metadata: prebackuppod: mariadb name: mariadb-prebackuppod spec: - backupCommand: |- - /bin/sh -c "dump=$(mktemp) - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --no-data --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - > $dump - && mysqldump --max-allowed-packet=500M --events --routines --quick - --add-locks --no-autocommit --single-transaction --no-create-db - --ignore-table=$BACKUP_DB_DATABASE.watchdog - --no-create-info --no-tablespaces - -h $BACKUP_DB_HOST - -u $BACKUP_DB_USERNAME - -p$BACKUP_DB_PASSWORD - $BACKUP_DB_DATABASE - >> $dump - && cat $dump && rm $dump" + backupCommand: /bin/sh -c "dump=$(mktemp) && mysqldump --max-allowed-packet=500M + --events --routines --quick --add-locks --no-autocommit --single-transaction --no-create-db + --no-data -h $BACKUP_DB_HOST -u $BACKUP_DB_USERNAME -p$BACKUP_DB_PASSWORD $BACKUP_DB_DATABASE + > $dump && mysqldump --max-allowed-packet=500M --events --routines --quick --add-locks + --no-autocommit --single-transaction --no-create-db --ignore-table=$BACKUP_DB_DATABASE.watchdog + --no-create-info -h $BACKUP_DB_HOST -u $BACKUP_DB_USERNAME -p$BACKUP_DB_PASSWORD + $BACKUP_DB_DATABASE >> $dump && cat $dump && rm $dump" fileExtension: .mariadb.sql pod: metadata: From f3ce74089b509fbd3ea2ef820edb38e9f49d5be5 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 5 Dec 2022 10:55:50 +1100 Subject: [PATCH 15/17] chore: add a featureflag wrap around k8upv2 support --- legacy/build-deploy-docker-compose.sh | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index a80fa1f0..94cc0f6e 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -1068,23 +1068,26 @@ set -x # Run the backup generation script +# check if k8up v2 feature flag is enabled +if [ "$(featureFlag K8UP_V2)" = enabled ]; then # build-tool doesn't do any capability checks yet, so do this for now -if [[ "${CAPABILITIES[@]}" =~ "k8up.io/v1/Schedule" ]]; then - if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then - # Create baas-repo-pw secret based on the project secret - kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) - fi - build-deploy-tool template backup-schedule --version v2 - # check if the existing schedule exists, and delete it - if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then - if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get schedules.backup.appuio.ch k8up-lagoon-backup-schedule &> /dev/null; then - kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete schedules.backup.appuio.ch k8up-lagoon-backup-schedule + if [[ "${CAPABILITIES[@]}" =~ "k8up.io/v1/Schedule" ]]; then + if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then + # Create baas-repo-pw secret based on the project secret + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) fi - if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get prebackuppods.backup.appuio.ch &> /dev/null; then - kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete prebackuppods.backup.appuio.ch --all + build-deploy-tool template backup-schedule --version v2 + # check if the existing schedule exists, and delete it + if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then + if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get schedules.backup.appuio.ch k8up-lagoon-backup-schedule &> /dev/null; then + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete schedules.backup.appuio.ch k8up-lagoon-backup-schedule + fi + if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get prebackuppods.backup.appuio.ch &> /dev/null; then + kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete prebackuppods.backup.appuio.ch --all + fi fi + K8UP_VERSION="v2" fi - K8UP_VERSION="v2" fi if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]] && [[ "$K8UP_VERSION" != "v2" ]]; then if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then From 52c8d418b6b8f04d6cc04f48537f706f76ab4991 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Mon, 5 Dec 2022 11:00:20 +1100 Subject: [PATCH 16/17] chore: add some messaging --- legacy/build-deploy-docker-compose.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index 94cc0f6e..2f22d537 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -1064,14 +1064,13 @@ currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")" patchBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "routeConfigurationComplete" "Route/Ingress Configuration" previousStepEnd=${currentStepEnd} beginBuildStep "Backup Configuration" -set -x - # Run the backup generation script # check if k8up v2 feature flag is enabled if [ "$(featureFlag K8UP_V2)" = enabled ]; then # build-tool doesn't do any capability checks yet, so do this for now if [[ "${CAPABILITIES[@]}" =~ "k8up.io/v1/Schedule" ]]; then + echo "Backups: generating k8up.io/v1 resources" if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then # Create baas-repo-pw secret based on the project secret kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) @@ -1080,9 +1079,11 @@ if [ "$(featureFlag K8UP_V2)" = enabled ]; then # check if the existing schedule exists, and delete it if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]]; then if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get schedules.backup.appuio.ch k8up-lagoon-backup-schedule &> /dev/null; then + echo "Backups: removing old backup.appuio.ch/v1alpha1 schedule" kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete schedules.backup.appuio.ch k8up-lagoon-backup-schedule fi if kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get prebackuppods.backup.appuio.ch &> /dev/null; then + echo "Backups: removing old backup.appuio.ch/v1alpha1 prebackuppods" kubectl --insecure-skip-tls-verify -n ${NAMESPACE} delete prebackuppods.backup.appuio.ch --all fi fi @@ -1090,6 +1091,7 @@ if [ "$(featureFlag K8UP_V2)" = enabled ]; then fi fi if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]] && [[ "$K8UP_VERSION" != "v2" ]]; then + echo "Backups: generating backup.appuio.ch/v1alpha1 resources" if ! kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get secret baas-repo-pw &> /dev/null; then # Create baas-repo-pw secret based on the project secret kubectl --insecure-skip-tls-verify -n ${NAMESPACE} create secret generic baas-repo-pw --from-literal=repo-pw=$(echo -n "${PROJECT_SECRET}-BAAS-REPO-PW" | sha256sum | cut -d " " -f 1) @@ -1098,7 +1100,6 @@ if [[ "${CAPABILITIES[@]}" =~ "backup.appuio.ch/v1alpha1/Schedule" ]] && [[ "$K8 fi # check for ISOLATION_NETWORK_POLICY feature flag, disabled by default -set +x if [ "$(featureFlag ISOLATION_NETWORK_POLICY)" = enabled ]; then # add namespace isolation network policy to deployment helm template isolation-network-policy /kubectl-build-deploy/helmcharts/isolation-network-policy \ From 05bfa8cb6d635f68e2ee6f9079475f91337f09a2 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Tue, 6 Dec 2022 10:50:33 +1100 Subject: [PATCH 17/17] chore: add primaryingress label to primary ingress --- internal/templating/ingress/templates_ingress.go | 4 ++++ .../ingress/test-resources/result-active-standby1.yaml | 1 + .../ingress/test-resources/result-custom-ingress1.yaml | 1 + .../template-ingress/test1-results/example.com.yaml | 1 + .../template-ingress/test10-results/standby.example.com.yaml | 1 + .../template-ingress/test11-results/content.example.com.yaml | 1 + .../template-ingress/test12-results/test1.example.com.yaml | 1 + .../template-ingress/test13-results/example.com.yaml | 1 + .../template-ingress/test14-results/example.com.yaml | 1 + .../template-ingress/test15-results/example.com.yaml | 1 + .../template-ingress/test16-results/example.com.yaml | 1 + .../template-ingress/test17-results/example.com.yaml | 1 + .../template-ingress/test18-results/example.com.yaml | 1 + .../template-ingress/test2-results/example.com.yaml | 1 + .../template-ingress/test3-results/example.com.yaml | 1 + .../template-ingress/test4-results/example.com.yaml | 1 + .../template-ingress/test5-results/multiproject1.com.yaml | 1 + .../template-ingress/test6-results/multiproject2.com.yaml | 1 + .../template-ingress/test7-results/example.com.yaml | 1 + .../test8-results/customdomain-will-be-main-domain.com.yaml | 1 + .../template-ingress/test9-results/active.example.com.yaml | 1 + 21 files changed, 24 insertions(+) diff --git a/internal/templating/ingress/templates_ingress.go b/internal/templating/ingress/templates_ingress.go index f6f53ceb..66dc8d1c 100644 --- a/internal/templating/ingress/templates_ingress.go +++ b/internal/templating/ingress/templates_ingress.go @@ -89,6 +89,10 @@ func GenerateIngressTemplate( primaryIngress, _ := url.Parse(lValues.Route) // check if monitoring enabled, route isn't autogenerated, and the primary ingress from the .lagoon.yml is this processed routedomain // and enable monitoring on the primary ingress only. + if !route.Autogenerated && primaryIngress.Host == routeDomain { + // add the primary ingress label to the domain that is detected as being primary + additionalLabels["lagoon.sh/primaryingress"] = "true" + } if lValues.Monitoring.Enabled && !route.Autogenerated && primaryIngress.Host == routeDomain { // only add the monitring annotations if monitoring is enabled additionalAnnotations["monitor.stakater.com/enabled"] = "true" diff --git a/internal/templating/ingress/test-resources/result-active-standby1.yaml b/internal/templating/ingress/test-resources/result-active-standby1.yaml index 0eb35993..0403c6fd 100644 --- a/internal/templating/ingress/test-resources/result-active-standby1.yaml +++ b/internal/templating/ingress/test-resources/result-active-standby1.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: environment-with-really-really-reall-3fdb lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: extra-long-name-f6c8a lagoon.sh/service-type: custom-ingress diff --git a/internal/templating/ingress/test-resources/result-custom-ingress1.yaml b/internal/templating/ingress/test-resources/result-custom-ingress1.yaml index 0469c297..b83eab4a 100644 --- a/internal/templating/ingress/test-resources/result-custom-ingress1.yaml +++ b/internal/templating/ingress/test-resources/result-custom-ingress1.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: environment-with-really-really-reall-3fdb lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: extra-long-name-f6c8a lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test1-results/example.com.yaml b/test-resources/template-ingress/test1-results/example.com.yaml index ace49c1c..03961f71 100644 --- a/test-resources/template-ingress/test1-results/example.com.yaml +++ b/test-resources/template-ingress/test1-results/example.com.yaml @@ -27,6 +27,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test10-results/standby.example.com.yaml b/test-resources/template-ingress/test10-results/standby.example.com.yaml index 263ea5cd..2903a40c 100644 --- a/test-resources/template-ingress/test10-results/standby.example.com.yaml +++ b/test-resources/template-ingress/test10-results/standby.example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main2 lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: standby.example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test11-results/content.example.com.yaml b/test-resources/template-ingress/test11-results/content.example.com.yaml index 6f60537a..6f345091 100644 --- a/test-resources/template-ingress/test11-results/content.example.com.yaml +++ b/test-resources/template-ingress/test11-results/content.example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: production lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: content-example-com lagoon.sh/service: content.example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test12-results/test1.example.com.yaml b/test-resources/template-ingress/test12-results/test1.example.com.yaml index a23c0658..4378214c 100644 --- a/test-resources/template-ingress/test12-results/test1.example.com.yaml +++ b/test-resources/template-ingress/test12-results/test1.example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: test1.example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test13-results/example.com.yaml b/test-resources/template-ingress/test13-results/example.com.yaml index d9e0eb15..26015585 100644 --- a/test-resources/template-ingress/test13-results/example.com.yaml +++ b/test-resources/template-ingress/test13-results/example.com.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test14-results/example.com.yaml b/test-resources/template-ingress/test14-results/example.com.yaml index 3a2a7a42..a84e825b 100644 --- a/test-resources/template-ingress/test14-results/example.com.yaml +++ b/test-resources/template-ingress/test14-results/example.com.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test15-results/example.com.yaml b/test-resources/template-ingress/test15-results/example.com.yaml index 3a2a7a42..a84e825b 100644 --- a/test-resources/template-ingress/test15-results/example.com.yaml +++ b/test-resources/template-ingress/test15-results/example.com.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test16-results/example.com.yaml b/test-resources/template-ingress/test16-results/example.com.yaml index a24149a4..2658b879 100644 --- a/test-resources/template-ingress/test16-results/example.com.yaml +++ b/test-resources/template-ingress/test16-results/example.com.yaml @@ -29,6 +29,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test17-results/example.com.yaml b/test-resources/template-ingress/test17-results/example.com.yaml index db0fab10..95dff4fe 100644 --- a/test-resources/template-ingress/test17-results/example.com.yaml +++ b/test-resources/template-ingress/test17-results/example.com.yaml @@ -29,6 +29,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test18-results/example.com.yaml b/test-resources/template-ingress/test18-results/example.com.yaml index 872863e6..721bda7c 100644 --- a/test-resources/template-ingress/test18-results/example.com.yaml +++ b/test-resources/template-ingress/test18-results/example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test2-results/example.com.yaml b/test-resources/template-ingress/test2-results/example.com.yaml index ec0d7a41..910ce5b3 100644 --- a/test-resources/template-ingress/test2-results/example.com.yaml +++ b/test-resources/template-ingress/test2-results/example.com.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test3-results/example.com.yaml b/test-resources/template-ingress/test3-results/example.com.yaml index ec0d7a41..910ce5b3 100644 --- a/test-resources/template-ingress/test3-results/example.com.yaml +++ b/test-resources/template-ingress/test3-results/example.com.yaml @@ -26,6 +26,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test4-results/example.com.yaml b/test-resources/template-ingress/test4-results/example.com.yaml index 872863e6..721bda7c 100644 --- a/test-resources/template-ingress/test4-results/example.com.yaml +++ b/test-resources/template-ingress/test4-results/example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test5-results/multiproject1.com.yaml b/test-resources/template-ingress/test5-results/multiproject1.com.yaml index 0ad28006..e4d99686 100644 --- a/test-resources/template-ingress/test5-results/multiproject1.com.yaml +++ b/test-resources/template-ingress/test5-results/multiproject1.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: multiproject lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: multiproject1 lagoon.sh/service: multiproject1.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test6-results/multiproject2.com.yaml b/test-resources/template-ingress/test6-results/multiproject2.com.yaml index 52ec7102..0c0d6fbf 100644 --- a/test-resources/template-ingress/test6-results/multiproject2.com.yaml +++ b/test-resources/template-ingress/test6-results/multiproject2.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: multiproject lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: multiproject2 lagoon.sh/service: multiproject2.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test7-results/example.com.yaml b/test-resources/template-ingress/test7-results/example.com.yaml index 872863e6..721bda7c 100644 --- a/test-resources/template-ingress/test7-results/example.com.yaml +++ b/test-resources/template-ingress/test7-results/example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: example.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test8-results/customdomain-will-be-main-domain.com.yaml b/test-resources/template-ingress/test8-results/customdomain-will-be-main-domain.com.yaml index 614d6690..ae3b1082 100644 --- a/test-resources/template-ingress/test8-results/customdomain-will-be-main-domain.com.yaml +++ b/test-resources/template-ingress/test8-results/customdomain-will-be-main-domain.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: branch-routes lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: customdomain-will-be-main-domain.com lagoon.sh/service-type: custom-ingress diff --git a/test-resources/template-ingress/test9-results/active.example.com.yaml b/test-resources/template-ingress/test9-results/active.example.com.yaml index 5c9025bd..44e060cc 100644 --- a/test-resources/template-ingress/test9-results/active.example.com.yaml +++ b/test-resources/template-ingress/test9-results/active.example.com.yaml @@ -25,6 +25,7 @@ metadata: lagoon.sh/buildType: branch lagoon.sh/environment: main lagoon.sh/environmentType: production + lagoon.sh/primaryingress: "true" lagoon.sh/project: example-project lagoon.sh/service: active.example.com lagoon.sh/service-type: custom-ingress