From e62bafb2255bec4d5e524df0fb09a77eebbd9ee4 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Wed, 4 Sep 2024 08:41:32 +0200 Subject: [PATCH 01/40] add workflow and tests --- .github/workflows/test-e2e-module-create.yml | 91 ++ ...ffold.yml => test-e2e-module-scaffold.yml} | 16 +- ...st-coverage.yml => test-unit-coverage.yml} | 0 .../{unit-test.yaml => test-unit.yaml} | 0 go.mod | 304 +++- go.sum | 1227 ++++++++++++++++- tests/e2e/Makefile | 10 +- tests/e2e/create/create_same_ver_test.go | 1 + tests/e2e/create/create_suite_test.go | 13 + tests/e2e/create/create_test.go | 163 +++ .../create/scaffold/scaffold_suite_test.go | 2 +- tests/e2e/create/scaffold/scaffold_test.go | 2 +- 12 files changed, 1809 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/test-e2e-module-create.yml rename .github/workflows/{e2e-test-create-scaffold.yml => test-e2e-module-scaffold.yml} (63%) rename .github/workflows/{verify-unit-test-coverage.yml => test-unit-coverage.yml} (100%) rename .github/workflows/{unit-test.yaml => test-unit.yaml} (100%) create mode 100644 tests/e2e/create/create_same_ver_test.go create mode 100644 tests/e2e/create/create_suite_test.go create mode 100644 tests/e2e/create/create_test.go diff --git a/.github/workflows/test-e2e-module-create.yml b/.github/workflows/test-e2e-module-create.yml new file mode 100644 index 00000000..2b837fdb --- /dev/null +++ b/.github/workflows/test-e2e-module-create.yml @@ -0,0 +1,91 @@ +name: E2E test - module create +on: + push: + branches: + - main + - 'release-**' + pull_request: + branches: + - main + - 'release-**' +jobs: + e2e: + strategy: + matrix: + e2e-test: [ 'test-module-create', + 'test-module-create-same-version' ] + name: E2E test - module create + runs-on: ubuntu-latest + env: + K3D_VERSION: v5.4.7 + MODULE_TEMPLATE_VERSION: 1.0.0 + OCI_REPOSITORY_URL: http://k3d-oci.localhost:5001 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Go setup + uses: actions/setup-go@v4 + with: + go-version-file: 'go.mod' + cache-dependency-path: 'go.sum' + - name: Build + run: | + make build-linux + chmod +x ./bin/modulectl-linux + ls -la ./bin + mv ./bin/modulectl-linux /usr/local/bin/modulectl + timeout-minutes: 5 + - name: Checkout template-operator + uses: actions/checkout@v4 + with: + repository: kyma-project/template-operator + path: ./template-operator/ + - name: export template-operator URL + run: | + cd ./template-operator + echo "TEST_REPOSITORY_URL=$(git remote get-url origin)" >> "$GITHUB_ENV" + - name: Set up k3d + run: wget -qO - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=$K3D_VERSION bash + - name: Provision OCI Registry + run: | + k3d registry create oci.localhost --port 5001 + - name: Run create module with module-config + run: | + cd ./template-operator + make build-manifests + modulectl create \ + --name kyma-project.io/module/template-operator \ + --path . \ + --registry http://k3d-oci.localhost:5001 \ + --insecure \ + --module-config-file ./module-config.yaml \ + --version $MODULE_TEMPLATE_VERSION -v \ + --sec-scanners-config sec-scanners-config.yaml \ + --output /tmp/module-config-template.yaml + echo "MODULE_TEMPLATE_PATH=/tmp/module-config-template.yaml" >> "$GITHUB_ENV" + - name: Create a different security scanners config file for different layers + if: ${{matrix.e2e-test == 'test-module-create-same-version' }} + run: | + cd ./template-operator + echo \ + "module-name: template-operator + rc-tag: 0.5.0 + dev-branch: main + protecode: + - europe-west3-docker.pkg.dev/sap-kyma-jellyfish-dev/template-operator/component-descriptors/kyma-project.io/template-operator:v1.0.0-e2e-warning + whitesource: + language: golang-mod + exclude: + - \"**/test/**\" + - \"**/*_test.go\"" > sec-scanners-config-changed.yaml + cat sec-scanners-config-changed.yaml + - name: Verify module template + if: ${{ matrix.e2e-test == 'test-module-create' }} + run: | + echo $MODULE_TEMPLATE_PATH + make -C tests/e2e test-module-creation + - name: Run E2E tests + if: ${{ matrix.e2e-test == 'test-module-create-same-version'}} + run: | + echo $MODULE_TEMPLATE_PATH + make -C tests/e2e test-module-creation-same-version diff --git a/.github/workflows/e2e-test-create-scaffold.yml b/.github/workflows/test-e2e-module-scaffold.yml similarity index 63% rename from .github/workflows/e2e-test-create-scaffold.yml rename to .github/workflows/test-e2e-module-scaffold.yml index ba03bfba..0d5e4fb8 100644 --- a/.github/workflows/e2e-test-create-scaffold.yml +++ b/.github/workflows/test-e2e-module-scaffold.yml @@ -1,4 +1,4 @@ -name: E2E Test - Create Scaffold +name: E2E test - module scaffold on: pull_request: branches: @@ -6,24 +6,24 @@ on: - 'release-**' jobs: e2e-test: - name: E2E Test - Create Scaffold + name: E2E test - module scaffold runs-on: ubuntu-latest steps: - - name: Checkout modulectl + - name: Checkout uses: actions/checkout@v4 - - name: Set up Go + - name: Go setup uses: actions/setup-go@v4 with: go-version-file: 'go.mod' cache-dependency-path: 'go.sum' - - name: Build modulectl + - name: Build run: | make build-linux chmod +x ./bin/modulectl-linux ls -la ./bin mv ./bin/modulectl-linux /usr/local/bin/modulectl - timeout-minutes: 10 - - name: Run E2E Test - Create Scaffold + timeout-minutes: 5 + - name: Run E2E test - module scaffold run: | - make -C tests/e2e test-create-scaffold + make -C tests/e2e test-module-scaffold timeout-minutes: 3 diff --git a/.github/workflows/verify-unit-test-coverage.yml b/.github/workflows/test-unit-coverage.yml similarity index 100% rename from .github/workflows/verify-unit-test-coverage.yml rename to .github/workflows/test-unit-coverage.yml diff --git a/.github/workflows/unit-test.yaml b/.github/workflows/test-unit.yaml similarity index 100% rename from .github/workflows/unit-test.yaml rename to .github/workflows/test-unit.yaml diff --git a/go.mod b/go.mod index d8f51a75..0ac3cd5a 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,13 @@ module github.com/kyma-project/modulectl -go 1.22.4 +go 1.22.6 require ( github.com/Masterminds/semver/v3 v3.3.0 + github.com/kyma-project/lifecycle-manager/api v0.0.0-20240903130243-695e809e05b7 github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 + github.com/open-component-model/ocm v0.13.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 @@ -13,18 +15,312 @@ require ( ) require ( + cloud.google.com/go/auth v0.7.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect + github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.29 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect + github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect + github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect + github.com/ThalesIgnite/crypto11 v1.2.5 // indirect + github.com/a8m/envsubst v1.4.2 // indirect + github.com/alecthomas/participle/v2 v2.1.1 // indirect + github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect + github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect + github.com/alibabacloud-go/cr-20181201 v1.0.10 // indirect + github.com/alibabacloud-go/darabonba-openapi v0.2.1 // indirect + github.com/alibabacloud-go/debug v1.0.0 // indirect + github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect + github.com/alibabacloud-go/openapi-util v0.1.0 // indirect + github.com/alibabacloud-go/tea v1.2.1 // indirect + github.com/alibabacloud-go/tea-utils v1.4.5 // indirect + github.com/alibabacloud-go/tea-xml v1.1.3 // indirect + github.com/aliyun/credentials-go v1.3.1 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/aws/aws-sdk-go-v2 v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15 // indirect + github.com/aws/aws-sdk-go-v2/service/ecr v1.31.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.58.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect + github.com/aws/smithy-go v1.20.3 // indirect + github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/buildkite/agent/v3 v3.75.1 // indirect + github.com/buildkite/go-pipeline v0.10.0 // indirect + github.com/buildkite/interpolate v0.1.3 // indirect + github.com/buildkite/roko v1.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect + github.com/clbanning/mxj/v2 v2.7.0 // indirect + github.com/cloudflare/cfssl v1.6.5 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect + github.com/containerd/containerd v1.7.20 // indirect + github.com/containerd/errdefs v0.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect + github.com/containers/image/v5 v5.32.0 // indirect + github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect + github.com/containers/ocicrypt v1.2.0 // indirect + github.com/containers/storage v1.55.0 // indirect + github.com/coreos/go-oidc/v3 v3.11.0 // indirect + github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect + github.com/cyphar/filepath-securejoin v0.3.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect + github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect + github.com/dimchansky/utfbom v1.1.1 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/cli v27.1.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v27.1.1+incompatible // indirect + github.com/docker/docker-credential-helpers v0.8.2 // indirect + github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-metrics v0.0.1 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/elliotchance/orderedmap v1.6.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.1 // indirect + github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/fatih/color v1.17.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fvbommel/sortorder v1.1.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-chi/chi v4.1.2+incompatible // indirect + github.com/go-errors/errors v1.5.1 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-jose/go-jose/v4 v4.0.2 // indirect github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/analysis v0.23.0 // indirect + github.com/go-openapi/errors v0.22.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/loads v0.22.0 // indirect + github.com/go-openapi/runtime v0.28.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/strfmt v0.23.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/validate v0.24.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-test/deep v1.1.1 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-yaml v1.11.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/certificate-transparency-go v1.2.1 // indirect + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-containerregistry v0.20.1 // indirect + github.com/google/go-github/v45 v45.2.0 // indirect + github.com/google/go-github/v55 v55.0.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/gowebpki/jcs v1.0.1 // indirect + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect + github.com/hashicorp/vault-client-go v0.4.3 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/kr/pretty v0.3.1 // indirect + github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect + github.com/jinzhu/copier v0.4.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect + github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 // indirect + github.com/mandelsoft/goutils v0.0.0-20240623134558-383cb09dec16 // indirect + github.com/mandelsoft/logging v0.0.0-20240618075559-fdca28a87b0a // indirect + github.com/mandelsoft/spiff v1.7.0-beta-5 // indirect + github.com/mandelsoft/vfs v0.4.3 // indirect + github.com/marstr/guid v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/miekg/pkcs11 v1.1.1 // indirect + github.com/mikefarah/yq/v4 v4.44.2 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/locker v1.0.1 // indirect + github.com/moby/sys/mountinfo v0.7.2 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.2.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/mozillazg/docker-credential-acr-helper v0.3.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect + github.com/oklog/ulid v1.3.1 // indirect + github.com/oleiade/reflections v1.0.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pborman/uuid v1.2.1 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/redis/go-redis/v9 v9.6.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sassoftware/relic v7.2.1+incompatible // indirect + github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect + github.com/segmentio/ksuid v1.0.4 // indirect + github.com/shibumi/go-pathspec v1.3.0 // indirect + github.com/sigstore/cosign/v2 v2.3.0 // indirect + github.com/sigstore/fulcio v1.5.1 // indirect + github.com/sigstore/rekor v1.3.6 // indirect + github.com/sigstore/sigstore v1.8.7 // indirect + github.com/sigstore/timestamp-authority v1.2.2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/viper v1.19.0 // indirect + github.com/spiffe/go-spiffe/v2 v2.3.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c // indirect + github.com/thales-e-security/pool v0.0.2 // indirect + github.com/theupdateframework/go-tuf v0.7.0 // indirect + github.com/theupdateframework/notary v0.7.0 // indirect + github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect + github.com/tonglil/buflogr v1.1.1 // indirect + github.com/transparency-dev/merkle v0.0.2 // indirect + github.com/ulikunitz/xz v0.5.12 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/vbatts/tar-split v0.11.5 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xanzy/go-gitlab v0.107.0 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xlab/treeprint v1.2.0 // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect + github.com/zeebo/errs v1.3.0 // indirect + go.mongodb.org/mongo-driver v1.14.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.starlark.net v0.0.0-20231121155337-90ade8b19d09 // indirect + go.step.sm/crypto v0.50.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + google.golang.org/api v0.188.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + helm.sh/helm/v3 v3.15.3 // indirect + k8s.io/api v0.31.0 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/apimachinery v0.31.0 // indirect + k8s.io/cli-runtime v0.30.3 // indirect + k8s.io/client-go v0.31.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + oras.land/oras-go v1.2.5 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.17.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.0 // indirect + sigs.k8s.io/release-utils v0.8.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index d358346d..24e98feb 100644 --- a/go.sum +++ b/go.sum @@ -1,55 +1,1274 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.0 h1:kf/x9B3WTbBUHkC+1VS8wwwli9TzhSt0vSTVBmMR8Ts= +cloud.google.com/go/auth v0.7.0/go.mod h1:D+WqdrpcjmiCgWrXmLLxOVq1GACoE36chW6KXoEvuIw= +cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= +cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/iam v1.1.10 h1:ZSAr64oEhQSClwBL670MsJAW5/RLiC6kfw3Bqmd5ZDI= +cloud.google.com/go/iam v1.1.10/go.mod h1:iEgMq62sg8zx446GCaijmA2Miwg5o3UbO+nI47WHJps= +cloud.google.com/go/kms v1.18.2 h1:EGgD0B9k9tOOkbPhYW1PHo2W0teamAUYMOUIcDRMfPk= +cloud.google.com/go/kms v1.18.2/go.mod h1:YFz1LYrnGsXARuRePL729oINmN5J/5e7nYijgvfiIeY= +cloud.google.com/go/longrunning v0.5.9 h1:haH9pAuXdPAMqHvzX0zlWQigXT7B0+CL4/2nXXdBo5k= +cloud.google.com/go/longrunning v0.5.9/go.mod h1:HD+0l9/OOW0za6UWdKJtXoFAX/BGg/3Wj8p10NeWF7c= +cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w= +cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2/go.mod h1:pK23AUVXuNzzTpfMCA06sxZGeVQ/75FdVtW249de9Uo= +cuelang.org/go v0.9.2 h1:pfNiry2PdRBr02G/aKm5k2vhzmqbAOoaB4WurmEbWvs= +cuelang.org/go v0.9.2/go.mod h1:qpAYsLOf7gTM1YdEg6cxh553uZ4q9ZDWlPbtZr9q1Wk= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d h1:zjqpY4C7H15HjRPEenkS4SAn3Jy2eRRjkjZbGR30TOg= +github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d/go.mod h1:XNqJ7hv2kY++g8XEHREpi+JqZo3+0l+CH2egBVN4yqM= +github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 h1:8+4G8JaejP8Xa6W46PzJEwisNgBXMvFcz78N6zG/ARw= +github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0/go.mod h1:GgeIE+1be8Ivm7Sh4RgwI42aTtC9qrcj+Y9Y6CjJhJs= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.1.0 h1:DRiANoJTiW6obBQe3SqZizkuV1PEgfiiGivmVocDy64= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.1.0/go.mod h1:qLIye2hwb/ZouqhpSD9Zn3SJipvpEnz1Ywl3VUk9Y0s= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= +github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= +github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0= +github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E= +github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE= +github.com/a8m/envsubst v1.4.2 h1:4yWIHXOLEJHQEFd4UjrWDrYeYlV7ncFWJOCBRLOZHQg= +github.com/a8m/envsubst v1.4.2/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= +github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= +github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= +github.com/alibabacloud-go/cr-20160607 v1.0.1 h1:WEnP1iPFKJU74ryUKh/YDPHoxMZawqlPajOymyNAkts= +github.com/alibabacloud-go/cr-20160607 v1.0.1/go.mod h1:QHeKZtZ3F3FOE+/uIXCBAp8POwnUYekpLwr1dtQa5r0= +github.com/alibabacloud-go/cr-20181201 v1.0.10 h1:B60f6S1imsgn2fgC6X6FrVNrONDrbCT0NwYhsJ0C9/c= +github.com/alibabacloud-go/cr-20181201 v1.0.10/go.mod h1:VN9orB/w5G20FjytoSpZROqu9ZqxwycASmGqYUJSoDc= +github.com/alibabacloud-go/darabonba-openapi v0.1.12/go.mod h1:sTAjsFJmVsmcVeklL9d9uDBlFsgl43wZ6jhI6BHqHqU= +github.com/alibabacloud-go/darabonba-openapi v0.1.14/go.mod h1:w4CosR7O/kapCtEEMBm3JsQqWBU/CnZ2o0pHorsTWDI= +github.com/alibabacloud-go/darabonba-openapi v0.2.1 h1:WyzxxKvhdVDlwpAMOHgAiCJ+NXa6g5ZWPFEzaK/ewwY= +github.com/alibabacloud-go/darabonba-openapi v0.2.1/go.mod h1:zXOqLbpIqq543oioL9IuuZYOQgHQ5B8/n5OPrnko8aY= +github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA= +github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY= +github.com/alibabacloud-go/debug v1.0.0 h1:3eIEQWfay1fB24PQIEzXAswlVJtdQok8f3EVN5VrBnA= +github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= +github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9GQdZO3mcSUTUy8= +github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= +github.com/alibabacloud-go/openapi-util v0.0.9/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/openapi-util v0.0.10/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY= +github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= +github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.2.1 h1:rFF1LnrAdhaiPmKwH5xwYOKlMh66CqRwPUTzIK74ask= +github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2wSyEUo4OEmnA= +github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= +github.com/alibabacloud-go/tea-utils v1.3.9/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= +github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= +github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA= +github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= +github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= +github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= +github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= +github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= +github.com/aliyun/credentials-go v1.3.1 h1:uq/0v7kWrxmoLGpqjx7vtQ/s03f0zR//0br/xWDTE28= +github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.54.19 h1:tyWV+07jagrNiCcGRzRhdtVjQs7Vy41NwsuOcl0IbVI= +github.com/aws/aws-sdk-go v1.54.19/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= +github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= +github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM= +github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= +github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= +github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.9 h1:TC2vjvaAv1VNl9A0rm+SeuBjrzXnrlwk6Yop+gKRi38= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.9/go.mod h1:WPv2FRnkIOoDv/8j2gSUsI4qDc7392w5anFB/I89GZ8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15 h1:Z5r7SycxmSllHYmaAZPpmN8GviDrSGhMS6bldqtXZPw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15/go.mod h1:CetW7bDE00QoGEmPUoZuRog07SGVAUVW6LFpNP0YfIg= +github.com/aws/aws-sdk-go-v2/service/ecr v1.31.0 h1:vi/MwojjLGATEEUFn2GEdLiom7CFlB+qCIx4tDWqKfQ= +github.com/aws/aws-sdk-go-v2/service/ecr v1.31.0/go.mod h1:RhaP7Wil0+uuuhiE4FzOOEFZwkmFAk1ZflXzK+O3ptU= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 h1:PpbXaecV3sLAS6rjQiaKw4/jyq3Z8gNzmoJupHAoBp0= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2/go.mod h1:fUHpGXr4DrXkEDpGAjClPsviWf+Bszeb0daKE0blxv8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17 h1:YPYe6ZmvUfDDDELqEKtAd6bo8zxhkm+XEFEzQisqUIE= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17/go.mod h1:oBtcnYua/CgzCWYN7NZ5j7PotFDaFSUjCYVTtfyn7vw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15 h1:246A4lSTXWJw/rmlQI+TT2OcqeDMKBdyjEQrafMaQdA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15/go.mod h1:haVfg3761/WF7YPuJOER2MP0k4UAXyHaLclKXB6usDg= +github.com/aws/aws-sdk-go-v2/service/kms v1.35.1 h1:0gP2OJJT6HM2BYltZ9x+A87OE8LJL96DXeAAdLv3t1M= +github.com/aws/aws-sdk-go-v2/service/kms v1.35.1/go.mod h1:hGONorZkQCfR5DW6l2xdy7zC8vfO0r9pJlwyg6gmGeo= +github.com/aws/aws-sdk-go-v2/service/s3 v1.58.2 h1:sZXIzO38GZOU+O0C+INqbH7C2yALwfMWpd64tONS/NE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.58.2/go.mod h1:Lcxzg5rojyVPU/0eFwLtcyTaek/6Mtic5B1gJo7e/zE= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= +github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= +github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 h1:SoFYaT9UyGkR0+nogNyD/Lj+bsixB+SNuAS4ABlEs6M= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8/go.mod h1:2JF49jcDOrLStIXN/j/K1EKRq8a8R2qRnlZA6/o/c7c= +github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0 h1:s7+5BfS4WFJoVF9pnB8kBk03S7pZXRdKamnV0FOl5Sc= +github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/buildkite/agent/v3 v3.75.1 h1:FJg1gss9nUESExTsfx6yWqs/g20Vyd4pHSEB9iuT4pI= +github.com/buildkite/agent/v3 v3.75.1/go.mod h1:UXCAEaqJnw5UsoZjJ9NxMvdSGc4oMHBnQFQqzGPDM0Y= +github.com/buildkite/go-pipeline v0.10.0 h1:EDffu+LfMY2k5u+iEdo6Jn3obGKsrL5wicc1O/yFeRs= +github.com/buildkite/go-pipeline v0.10.0/go.mod h1:eMH1kiav5VeiTiu0Mk2/M7nZhKyFeL4iGj7Y7rj4f3w= +github.com/buildkite/interpolate v0.1.3 h1:OFEhqji1rNTRg0u9DsSodg63sjJQEb1uWbENq9fUOBM= +github.com/buildkite/interpolate v0.1.3/go.mod h1:UNVe6A+UfiBNKbhAySrBbZFZFxQ+DXr9nWen6WVt/A8= +github.com/buildkite/roko v1.2.0 h1:hbNURz//dQqNl6Eo9awjQOVOZwSDJ8VEbBDxSfT9rGQ= +github.com/buildkite/roko v1.2.0/go.mod h1:23R9e6nHxgedznkwwfmqZ6+0VJZJZ2Sg/uVcp2cP46I= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= +github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= +github.com/cloudflare/cfssl v1.6.5 h1:46zpNkm6dlNkMZH/wMW22ejih6gIaJbzL2du6vD7ZeI= +github.com/cloudflare/cfssl v1.6.5/go.mod h1:Bk1si7sq8h2+yVEDrFJiz3d7Aw+pfjjJSZVaD+Taky4= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudfoundry-incubator/candiedyaml v0.0.0-20170901234223-a41693b7b7af h1:6Cpkahw28+gcBdnXQL7LcMTX488+6jl6hfoTMRT6Hm4= +github.com/cloudfoundry-incubator/candiedyaml v0.0.0-20170901234223-a41693b7b7af/go.mod h1:dOLSIXcRQJiDS1vlrYFNJicoHNZLsBKideE+70hGdV4= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= +github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= +github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= +github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= +github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= +github.com/containerd/containerd v1.7.20 h1:Sl6jQYk3TRavaU83h66QMbI2Nqg9Jm6qzwX57Vsn1SQ= +github.com/containerd/containerd v1.7.20/go.mod h1:52GsS5CwquuqPuLncsXwG0t2CiUce+KsNHJZQJvAgR0= +github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= +github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= +github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= +github.com/containers/image/v5 v5.32.0 h1:yjbweazPfr8xOzQ2hkkYm1A2V0jN96/kES6Gwyxj7hQ= +github.com/containers/image/v5 v5.32.0/go.mod h1:x5e0RDfGaY6bnQ13gJ2LqbfHvzssfB/y5a8HduGFxJc= +github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= +github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= +github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM= +github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U= +github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg= +github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ= +github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= +github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.19 h1:tUN6H7LWqNx4hQVxomd0CVsDwaDr9gaRQaI4GpSmrsA= +github.com/creack/pty v1.1.19/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f h1:eHnXnuK47UlSTOQexbzxAZfekVz6i+LKRdj1CU5DPaM= +github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= +github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE= +github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= +github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs= +github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/depcheck-test/depcheck-test v0.0.0-20220607135614-199033aaa936 h1:foGzavPWwtoyBvjWyKJYDYsyzy+23iBV7NKTwdk+LRY= +github.com/depcheck-test/depcheck-test v0.0.0-20220607135614-199033aaa936/go.mod h1:ttKPnOepYt4LLzD+loXQ1rT6EmpyIYHro7TAJuIIlHo= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= +github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 h1:ge14PCmCvPjpMQMIAH7uKg0lrtNSOdpYsRXlwk3QbaE= +github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= +github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 h1:lxmTCgmHE1GUYL7P0MlNa00M67axePTq+9nBSGddR8I= +github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7/go.mod h1:GvWntX9qiTlOud0WkQ6ewFm0LPy5JUR1Xo0Ngbd1w6Y= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= +github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= +github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= +github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= +github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/elliotchance/orderedmap v1.6.0 h1:xjn+kbbKXeDq6v9RVE+WYwRbYfAZKvlWfcJNxM8pvEw= +github.com/elliotchance/orderedmap v1.6.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys= +github.com/emicklei/go-restful/v3 v3.11.1 h1:S+9bSbua1z3FgCnV0KKOSSZ3mDthb5NyEPL5gEpCvyk= +github.com/emicklei/go-restful/v3 v3.11.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/proto v1.12.1 h1:6n/Z2pZAnBwuhU66Gs8160B8rrrYKo7h2F2sCOnNceE= +github.com/emicklei/proto v1.12.1/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= +github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= +github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= +github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= +github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= +github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= +github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= +github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= +github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= +github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= +github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= +github.com/go-piv/piv-go v1.11.0 h1:5vAaCdRTFSIW4PeqMbnsDlUZ7odMYWnHBDGdmtU/Zhg= +github.com/go-piv/piv-go v1.11.0/go.mod h1:NZ2zmjVkfFaL/CF8cVQ/pXdXtuj110zEKGdJM6fJZZM= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U= +github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-rod/rod v0.116.1 h1:BDMZY3qm/14SmvHBV7DoFUhXeJ2MbUYgumQ88b+v2WE= +github.com/go-rod/rod v0.116.1/go.mod h1:3Ash9fYwznqz9S1uLQgQRStur4fCXjoxxGW+ym6TYjU= +github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= +github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +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/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +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.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= +github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/certificate-transparency-go v1.2.1 h1:4iW/NwzqOqYEEoCBEFP+jPbBXbLqMpq3CifMyOnDUME= +github.com/google/certificate-transparency-go v1.2.1/go.mod h1:bvn/ytAccv+I6+DGkqpvSsEdiVGramgaSC6RD3tEmeE= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= +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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0= +github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI= +github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= +github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg= +github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w= +github.com/google/tink/go v1.7.0/go.mod h1:GAUOd+QE3pgj9q8VKIGTCP33c/B7eb4NhxLcgTJZStM= +github.com/google/trillian v1.6.0 h1:jMBeDBIkINFvS2n6oV5maDqfRlxREAc6CW9QYWQ0qT4= +github.com/google/trillian v1.6.0/go.mod h1:Yu3nIMITzNhhMJEHjAtp6xKiu+H/iHu2Oq5FjV2mCWI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= +github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gowebpki/jcs v1.0.1 h1:Qjzg8EOkrOTuWP7DqQ1FbYtcpEbeTzUoTN9bptp8FOU= +github.com/gowebpki/jcs v1.0.1/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.5 h1:dvk7TIXCZpmfOlM+9mlcrWmWjw/wlKT+VDq2wMvfPJU= +github.com/hashicorp/go-sockaddr v1.0.5/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/vault-client-go v0.4.3 h1:zG7STGVgn/VK6rnZc0k8PGbfv2x/sJExRKHSUg3ljWc= +github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j4sB9cp0T7U6m4FzDY= +github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU= +github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= +github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU= +github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= +github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE= +github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc= +github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= +github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +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/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyma-project/lifecycle-manager/api v0.0.0-20240903130243-695e809e05b7 h1:WTUspXigXUhzUd5a0JxC73UMCLd5XqoRkGwyt6uE2t8= +github.com/kyma-project/lifecycle-manager/api v0.0.0-20240903130243-695e809e05b7/go.mod h1:bJcxlY2l9sLJmb6ELl/8/p5Nl3EmL2zMPGL329i4uAs= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ= +github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= +github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 h1:oo9nIgnyiBgYPbcZslRT4y29siuL5EoNJ/t1tr0xEVQ= +github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= +github.com/mandelsoft/goutils v0.0.0-20240623134558-383cb09dec16 h1:7tcgfj+QZSfABuZKc9PrgQj1U+A7MsRySCG4ZG5JvLg= +github.com/mandelsoft/goutils v0.0.0-20240623134558-383cb09dec16/go.mod h1:9TJgkwSY43RWHiIAAz7fL8SEIHf0L13Pk4w8fDIt+i4= +github.com/mandelsoft/logging v0.0.0-20240618075559-fdca28a87b0a h1:MAvh0gbP2uwKmf7wWCkYCzrYa6vPjBvYeGhoUlVHwtI= +github.com/mandelsoft/logging v0.0.0-20240618075559-fdca28a87b0a/go.mod h1:uO460C1lIB3IOOgrbXhAlz3AKsOv4T2K6ALBn3PwuSg= +github.com/mandelsoft/spiff v1.7.0-beta-5 h1:3kC10nTviDQhL8diSxp7i4IC2iSiDg6KPbH1CAq7Lfw= +github.com/mandelsoft/spiff v1.7.0-beta-5/go.mod h1:TwEeOPuRZxlzQBCLEyVTlHmBSruSGGNdiQ2fovVJ8ao= +github.com/mandelsoft/vfs v0.4.3 h1:2UMrxQkMXkcHyuqSFhgFDupQ1fmqpKLZuu04DOHx1PA= +github.com/mandelsoft/vfs v0.4.3/go.mod h1:zmbhx2ueQc96buqNXg2S88McBMm2mNFNeyGSpSebrHw= +github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= +github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= +github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mikefarah/yq/v4 v4.44.2 h1:J+ezWCDTg+SUs0jXdcE0HIPH1+rEr0Tbn9Y1SwiWtH0= +github.com/mikefarah/yq/v4 v4.44.2/go.mod h1:9bnz36uZJDEyxdIjRronBcqStS953k3y3DrSRXr4F/w= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.2.0 h1:OnpapJsRp25vkhw8TFG6OLJODNh/3rEwRWtJ3kakwRM= +github.com/moby/sys/user v0.2.0/go.mod h1:RYstrcWOJpVh+6qzUqp2bU3eaRpdiQeKGlKitaH0PM8= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mozillazg/docker-credential-acr-helper v0.3.0 h1:DVWFZ3/O8BP6Ue3iS/Olw+G07u1hCq1EOVCDZZjCIBI= +github.com/mozillazg/docker-credential-acr-helper v0.3.0/go.mod h1:cZlu3tof523ujmLuiNUb6JsjtHcNA70u1jitrrdnuyA= +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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE= +github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481/go.mod h1:yKZQO8QE2bHlgozqWDiRVqTFlLQSj30K/6SAK8EeYFw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= +github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +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 v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= +github.com/open-component-model/ocm v0.13.0 h1:rm31Z7SpFzpxCIUagaFEUI4cSIS098Hf2H0dToV2nOA= +github.com/open-component-model/ocm v0.13.0/go.mod h1:+ovmIxTexDM2fcnfVg9uqJh22A7KOxwa/stNJn315yU= +github.com/open-policy-agent/opa v0.66.0 h1:DbrvfJQja0FBRcPOB3Z/BOckocN+M4ApNWyNhSRJt0w= +github.com/open-policy-agent/opa v0.66.0/go.mod h1:EIgNnJcol7AvQR/IcWLwL13k64gHVbNAVG46b2G+/EY= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +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= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= +github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf h1:014O62zIzQwvoD7Ekj3ePDF5bv9Xxy0w6AZk0qYbjUk= +github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGqpgjJU3DYAZeI05A= +github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk= +github.com/sassoftware/relic/v7 v7.6.2 h1:rS44Lbv9G9eXsukknS4mSjIAuuX+lMq/FnStgmZlUv4= +github.com/sassoftware/relic/v7 v7.6.2/go.mod h1:kjmP0IBVkJZ6gXeAu35/KCEfca//+PKM6vTAsyDPY+k= +github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= +github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= +github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= +github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= +github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= +github.com/sigstore/cosign/v2 v2.3.0 h1:rBLVdKMYuER0blmaKMfMNkvawBdK1lTMz2L5PtTPrI8= +github.com/sigstore/cosign/v2 v2.3.0/go.mod h1:tjACBZS6LoH3bap5hU8MxyGC4DIJiatqhZxuJWFcIJ0= +github.com/sigstore/fulcio v1.5.1 h1:Iasy1zfNjaq8BV4S8o6pXspLDU28PQC2z07GmOu9zpM= +github.com/sigstore/fulcio v1.5.1/go.mod h1:W1A/UHrTopy1IBZPMtHmxg7GPYAu+vt5dRXM3W6yjPo= +github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8= +github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc= +github.com/sigstore/sigstore v1.8.7 h1:L7/zKauHTg0d0Hukx7qlR4nifh6T6O6UIt9JBwAmTIg= +github.com/sigstore/sigstore v1.8.7/go.mod h1:MPiQ/NIV034Fc3Kk2IX9/XmBQdK60wfmpvgK9Z1UjRA= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.7 h1:SoahswHQm2JhO8h3KTAeX8IZeE7mSR2Lc53ay5choes= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.7/go.mod h1:TOVOPOqldrrz4dP7x4/0DFQTs9QSXZUoHu21+JHmixA= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.7 h1:jcdKxc5bvwfL7+ZbeCszaN/qsBd6180fGAHxeX5Ckm0= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.7/go.mod h1:gakVcpRiN+aFdLhPXXP8ubOCWiedM1YJ/gR74ez/tT0= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.7 h1:zYg1XlbKpQkmE7FpWTkLuUn7RttLAq4FcZ1G9JcqhoY= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.7/go.mod h1:VmUsO1R4OHuyHBEgI4bbSUn0z2nojszrDMvlDxyX/dE= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.7 h1:dbcB9VEddYrvK+y4rHeES5OZ/pMQuucfJ0qCNWQmnp0= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.7/go.mod h1:96MrPJBkHiAvqFyqviuYbwPAdbPCj8CR3V0RJ9bKjrE= +github.com/sigstore/timestamp-authority v1.2.2 h1:X4qyutnCQqJ0apMewFyx+3t7Tws00JQ/JonBiu3QvLE= +github.com/sigstore/timestamp-authority v1.2.2/go.mod h1:nEah4Eq4wpliDjlY342rXclGSO7Kb9hoRrl9tqLW13A= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= +github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/spiffe/go-spiffe/v2 v2.3.0 h1:g2jYNb/PDMB8I7mBGL2Zuq/Ur6hUhoroxGQFyD6tTj8= +github.com/spiffe/go-spiffe/v2 v2.3.0/go.mod h1:Oxsaio7DBgSNqhAO9i/9tLClaVlfRok7zvJnTV8ZyIY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= +github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c h1:HelZ2kAFadG0La9d+4htN4HzQ68Bm2iM9qKMSMES6xg= +github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c/go.mod h1:JlzghshsemAMDGZLytTFY8C1JQxQPhnatWqNwUXjggo= +github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gtvVDbmPg= +github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= +github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= +github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug= +github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= +github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= +github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= +github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= +github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= +github.com/tonglil/buflogr v1.1.1 h1:CKAjOHBSMmgbRFxpn/RhQHPj5oANc7ekhlsoUDvcZIg= +github.com/tonglil/buflogr v1.1.1/go.mod h1:WLLtPRLqcFYWQLbA+ytXy5WrFTYnfA+beg1MpvJCxm4= +github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4= +github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= +github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= +github.com/weppos/publicsuffix-go v0.30.3-0.20240510084413-5f1d03393b3d h1:q80YKUcDWRNvvQcziH63e3ammTWARwrhohBCunHaYAg= +github.com/weppos/publicsuffix-go v0.30.3-0.20240510084413-5f1d03393b3d/go.mod h1:vLdXKydr/OJssAXmjY0XBgLXUfivBMrNRIBljgtqCnw= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xanzy/go-gitlab v0.107.0 h1:P2CT9Uy9yN9lJo3FLxpMZ4xj6uWcpnigXsjvqJ6nd2Y= +github.com/xanzy/go-gitlab v0.107.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg= +github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= +github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ= +github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns= +github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ= +github.com/ysmood/goob v0.4.0/go.mod h1:u6yx7ZhS4Exf2MwciFr6nIM8knHQIE22lFpWHnfql18= +github.com/ysmood/got v0.40.0 h1:ZQk1B55zIvS7zflRrkGfPDrPG3d7+JOza1ZkNxcc74Q= +github.com/ysmood/got v0.40.0/go.mod h1:W7DdpuX6skL3NszLmAsC5hT7JAhuLZhByVzHTq874Qg= +github.com/ysmood/gson v0.7.3 h1:QFkWbTH8MxyUTKPkVWAENJhxqdBa4lYTQWqZCiLG6kE= +github.com/ysmood/gson v0.7.3/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg= +github.com/ysmood/leakless v0.8.0 h1:BzLrVoiwxikpgEQR0Lk8NyBN5Cit2b1z+u0mgL4ZJak= +github.com/ysmood/leakless v0.8.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= +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 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97yms= +github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= +github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= +github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c h1:U1b4THKcgOpJ+kILupuznNwPiURtwVW3e9alJvji9+s= +github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c/go.mod h1:GSDpFDD4TASObxvfZfvpZZ3OWHIUHMlhVWlkOe4ewVk= +github.com/zmap/zlint/v3 v3.6.0 h1:vTEaDRtYN0d/1Ax60T+ypvbLQUHwHxbvYRnUMVr35ug= +github.com/zmap/zlint/v3 v3.6.0/go.mod h1:NVgiIWssgzp0bNl8P4Gz94NHV2ep/4Jyj9V69uTmZyg= +go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= +go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.starlark.net v0.0.0-20231121155337-90ade8b19d09 h1:hzy3LFnSN8kuQK8h9tHl4ndF6UruMj47OqwqsS+/Ai4= +go.starlark.net v0.0.0-20231121155337-90ade8b19d09/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= +go.step.sm/crypto v0.50.0 h1:BqI9sEgocoHDLLHiZnFqdqXl5FjdMvOWKMm/fKL/lrw= +go.step.sm/crypto v0.50.0/go.mod h1:NCFMhLS6FJXQ9sD9PP282oHtsBWLrI6wXZY0eOkq7t8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +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= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +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-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= +google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20240708141625-4ad9e859172b h1:dSTjko30weBaMj3eERKc0ZVXW4GudCswM3m+P++ukU0= +google.golang.org/genproto v0.0.0-20240708141625-4ad9e859172b/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= +gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE= +gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= +gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM= +gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +helm.sh/helm/v3 v3.15.3 h1:HcZDaVFe9uHa6hpsR54mJjYyRy4uz/pc6csg27nxFOc= +helm.sh/helm/v3 v3.15.3/go.mod h1:FzSIP8jDQaa6WAVg9F+OkKz7J0ZmAga4MABtTbsb9WQ= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= +k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= +k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/cli-runtime v0.30.3 h1:aG69oRzJuP2Q4o8dm+f5WJIX4ZBEwrvdID0+MXyUY6k= +k8s.io/cli-runtime v0.30.3/go.mod h1:hwrrRdd9P84CXSKzhHxrOivAR9BRnkMt0OeP5mj7X30= +k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= +k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= +oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.17.1 h1:MYJBOP/yQ3/5tp4/sf6HiiMfNNyO97LmtnirH9SLNr4= +sigs.k8s.io/kustomize/api v0.17.1/go.mod h1:ffn5491s2EiNrJSmgqcWGzQUVhc/pB0OKNI0HsT/0tA= +sigs.k8s.io/kustomize/kyaml v0.17.0 h1:G2bWs03V9Ur2PinHLzTUJ8Ded+30SzXZKiO92SRDs3c= +sigs.k8s.io/kustomize/kyaml v0.17.0/go.mod h1:6lxkYF1Cv9Ic8g/N7I86cvxNc5iinUo/P2vKsHNmpyE= +sigs.k8s.io/release-utils v0.8.3 h1:KtOtA4qDmzJyeQ2zkDsFVI25+NViwms/o5eL2NftFdA= +sigs.k8s.io/release-utils v0.8.3/go.mod h1:fp82Fma06OXBhEJ+GUJKqvcplDBomruK1R/1fWJnsrQ= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= +software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 9e4b7d22..1b6859e8 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -13,5 +13,11 @@ SHELL = /usr/bin/env bash -o pipefail ##@ E2E Tests -test-create-scaffold: - go test ./create/scaffold -ginkgo.v -ginkgo.focus "Create Scaffold Command" +test-module-scaffold: + go test ./create/scaffold -ginkgo.v -ginkgo.focus "Scaffold Command Test Suite" + +test-module-create: + go test ./create/scaffold -ginkgo.v -ginkgo.focus "Module Command Test Suite" + +test-module-create-same-version: + go test ./create/scaffold -ginkgo.v -ginkgo.focus "Module Command with same version" diff --git a/tests/e2e/create/create_same_ver_test.go b/tests/e2e/create/create_same_ver_test.go new file mode 100644 index 00000000..ef4f218a --- /dev/null +++ b/tests/e2e/create/create_same_ver_test.go @@ -0,0 +1 @@ +package create diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go new file mode 100644 index 00000000..26bf8467 --- /dev/null +++ b/tests/e2e/create/create_suite_test.go @@ -0,0 +1,13 @@ +package create_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestModuleCreate(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "'Create' Command Test Suite") +} diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go new file mode 100644 index 00000000..0ff2ddf7 --- /dev/null +++ b/tests/e2e/create/create_test.go @@ -0,0 +1,163 @@ +package create_test + +import ( + "github.com/kyma-project/lifecycle-manager/api/v1beta2" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + "gopkg.in/yaml.v3" + "os" + "testing" + + "github.com/kyma-project/lifecycle-manager/api/shared" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" + + "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" + "github.com/open-component-model/ocm/pkg/contexts/ocm" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" + ocmMetaV1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + v2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" + ocmOCIReg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" + "github.com/stretchr/testify/assert" +) + +const ( + rawManifestLayerName = "raw-manifest" + typeYaml = "yaml" +) + +func Test_ModuleTemplate(t *testing.T) { + ociRepoURL := os.Getenv("OCI_REPOSITORY_URL") + testRepoURL := os.Getenv("TEST_REPOSITORY_URL") + templatePath := os.Getenv("MODULE_TEMPLATE_PATH") + + template, err := readModuleTemplate(templatePath) + assert.Nil(t, err) + descriptor := getDescriptor(template) + assert.NotNil(t, descriptor) + assert.Equal(t, descriptor.SchemaVersion(), v2.SchemaVersion) + + t.Run("test annotations", func(t *testing.T) { + annotations := template.Annotations + expectedModuleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") + assert.Equal(t, expectedModuleTemplateVersion, annotations[shared.ModuleVersionAnnotation]) + assert.Equal(t, "false", annotations[shared.IsClusterScopedAnnotation]) + }) + + t.Run("test descriptor.component.repositoryContexts", func(t *testing.T) { + assert.Equal(t, 1, len(descriptor.RepositoryContexts)) + repo := descriptor.GetEffectiveRepositoryContext() + assert.Equal(t, ociRepoURL, repo.Object["baseUrl"]) + assert.Equal(t, string(ocmOCIReg.OCIRegistryURLPathMapping), repo.Object["componentNameMapping"]) + assert.Equal(t, ocireg.Type, repo.Object["type"]) + }) + + t.Run("test descriptor.component.resources", func(t *testing.T) { + assert.Equal(t, 2, len(descriptor.Resources)) + + resource := descriptor.Resources[0] + assert.Equal(t, "template-operator", resource.Name) + assert.Equal(t, ocmMetaV1.ExternalRelation, resource.Relation) + assert.Equal(t, "ociImage", resource.Type) + expectedModuleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") + assert.Equal(t, expectedModuleTemplateVersion, resource.Version) + + resource = descriptor.Resources[1] + assert.Equal(t, rawManifestLayerName, resource.Name) + assert.Equal(t, ocmMetaV1.LocalRelation, resource.Relation) + assert.Equal(t, typeYaml, resource.Type) + assert.Equal(t, expectedModuleTemplateVersion, resource.Version) + }) + + t.Run("test descriptor.component.resources[0].access", func(t *testing.T) { + resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) + assert.Nil(t, err) + ociArtifactAccessSpec, ok := resourceAccessSpec.(*ociartifact.AccessSpec) + assert.True(t, ok) + assert.Equal(t, ociartifact.Type, ociArtifactAccessSpec.GetType()) + assert.Equal(t, "europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0", + ociArtifactAccessSpec.ImageReference) + }) + + t.Run("test descriptor.component.resources[1].access", func(t *testing.T) { + resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) + assert.Nil(t, err) + localBlobAccessSpec, ok := resourceAccessSpec.(*localblob.AccessSpec) + assert.True(t, ok) + assert.Equal(t, localblob.Type, localBlobAccessSpec.GetType()) + assert.Contains(t, localBlobAccessSpec.LocalReference, "sha256:") + }) + + t.Run("test descriptor.component.sources", func(t *testing.T) { + assert.Equal(t, len(descriptor.Sources), 1) + source := descriptor.Sources[0] + sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) + assert.Nil(t, err) + githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) + assert.True(t, ok) + assert.Equal(t, github.Type, githubAccessSpec.Type) + assert.Contains(t, testRepoURL, githubAccessSpec.RepoURL) + }) + + t.Run("test spec.mandatory", func(t *testing.T) { + assert.Equal(t, false, template.Spec.Mandatory) + }) + + t.Run("test security scan labels", func(t *testing.T) { + secScanLabels := descriptor.Sources[0].Labels + flattenedLabels := flatten(secScanLabels) + assert.Equal(t, map[string]string{ + "git.kyma-project.io/ref": "refs/heads/main", + "scan.security.kyma-project.io/rc-tag": "1.0.0", + "scan.security.kyma-project.io/language": "golang-mod", + "scan.security.kyma-project.io/dev-branch": "main", + "scan.security.kyma-project.io/subprojects": "false", + "scan.security.kyma-project.io/exclude": "**/test/**,**/*_test.go", + }, flattenedLabels) + }) +} + +func readModuleTemplate(filepath string) (*v1beta2.ModuleTemplate, error) { + moduleTemplate := &v1beta2.ModuleTemplate{} + moduleFile, err := os.ReadFile(filepath) + if err != nil { + return nil, err + } + err = yaml.Unmarshal(moduleFile, &moduleTemplate) + + return moduleTemplate, err +} + +func getDescriptor(template *v1beta2.ModuleTemplate) *v1beta2.Descriptor { + if template.Spec.Descriptor.Object != nil { + desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) + if !ok || desc == nil { + return nil + } + return desc + } + ocmDesc, err := compdesc.Decode( + template.Spec.Descriptor.Raw, + []compdesc.DecodeOption{compdesc.DisableValidation(true)}...) + if err != nil { + return nil + } + template.Spec.Descriptor.Object = &v1beta2.Descriptor{ComponentDescriptor: ocmDesc} + desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) + if !ok { + return nil + } + + return desc +} + +func flatten(labels v1.Labels) map[string]string { + labelsMap := make(map[string]string) + for _, l := range labels { + var value string + _ = yaml.Unmarshal(l.Value, &value) + labelsMap[l.Name] = value + } + + return labelsMap +} diff --git a/tests/e2e/create/scaffold/scaffold_suite_test.go b/tests/e2e/create/scaffold/scaffold_suite_test.go index e6ebe3f6..4d6773cf 100644 --- a/tests/e2e/create/scaffold/scaffold_suite_test.go +++ b/tests/e2e/create/scaffold/scaffold_suite_test.go @@ -9,5 +9,5 @@ import ( func TestCreateScaffold(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "CreateScaffold Suite") + RunSpecs(t, "'Scaffold' Command Test Suite") } diff --git a/tests/e2e/create/scaffold/scaffold_test.go b/tests/e2e/create/scaffold/scaffold_test.go index 0ad77589..674af031 100644 --- a/tests/e2e/create/scaffold/scaffold_test.go +++ b/tests/e2e/create/scaffold/scaffold_test.go @@ -17,7 +17,7 @@ const ( markerFileData = "test-marker" ) -var _ = Describe("Create Scaffold Command", Ordered, func() { +var _ = Describe("Test 'Scaffold'", Ordered, func() { var initialDir string var workDir string From 716bf812694aa35a292c13acff7a2d974da80f27 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Wed, 4 Sep 2024 09:04:00 +0200 Subject: [PATCH 02/40] fmt --- tests/e2e/create/create_same_ver_test.go | 4 ++-- tests/e2e/create/create_test.go | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/e2e/create/create_same_ver_test.go b/tests/e2e/create/create_same_ver_test.go index e00dbd26..853f452a 100644 --- a/tests/e2e/create/create_same_ver_test.go +++ b/tests/e2e/create/create_same_ver_test.go @@ -46,7 +46,8 @@ func Test_SameVersion_ModuleCreation(t *testing.T) { } func createModuleCommand(versionOverwrite bool, - path, registry, configFilePath, version, secScannerConfig string) error { + path, registry, configFilePath, version, secScannerConfig string, +) error { var createModuleCmd *exec.Cmd if versionOverwrite { createModuleCmd = exec.Command("kyma", "alpha", "create", "module", @@ -58,7 +59,6 @@ func createModuleCommand(versionOverwrite bool, "--version", version, "--sec-scanners-config", secScannerConfig) } createOut, err := createModuleCmd.CombinedOutput() - if err != nil { if strings.Contains(string(createOut), fmt.Sprintf("version %s already exists with different content", version)) { diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 0ff2ddf7..47ad6f39 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -1,11 +1,12 @@ package create_test import ( + "os" + "testing" + "github.com/kyma-project/lifecycle-manager/api/v1beta2" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "gopkg.in/yaml.v3" - "os" - "testing" "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" From c70151df532c1894c24faf49bd405f3c31b1dc3b Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Wed, 4 Sep 2024 09:12:46 +0200 Subject: [PATCH 03/40] test --- .github/workflows/build.yaml | 6 +++--- .github/workflows/test-e2e-module-scaffold.yml | 6 +++--- tests/e2e/Makefile | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4c002922..18614268 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -10,12 +10,12 @@ jobs: name: Build modulectl runs-on: ubuntu-latest steps: - - name: Checkout modulectl + - name: Checkout uses: actions/checkout@v4 - - name: Set up Go + - name: Go setup uses: actions/setup-go@v4 with: go-version-file: 'go.mod' cache-dependency-path: 'go.sum' - - name: Run CLI Build + - name: "Run 'make build'" run: make build diff --git a/.github/workflows/test-e2e-module-scaffold.yml b/.github/workflows/test-e2e-module-scaffold.yml index 0d5e4fb8..2ac38ecf 100644 --- a/.github/workflows/test-e2e-module-scaffold.yml +++ b/.github/workflows/test-e2e-module-scaffold.yml @@ -1,4 +1,4 @@ -name: E2E test - module scaffold +name: "E2E test: modulectl scaffold" on: pull_request: branches: @@ -6,7 +6,7 @@ on: - 'release-**' jobs: e2e-test: - name: E2E test - module scaffold + name: E2E test - modulectl scaffold runs-on: ubuntu-latest steps: - name: Checkout @@ -23,7 +23,7 @@ jobs: ls -la ./bin mv ./bin/modulectl-linux /usr/local/bin/modulectl timeout-minutes: 5 - - name: Run E2E test - module scaffold + - name: Run tests run: | make -C tests/e2e test-module-scaffold timeout-minutes: 3 diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 1b6859e8..49dd6b5a 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -14,7 +14,7 @@ SHELL = /usr/bin/env bash -o pipefail ##@ E2E Tests test-module-scaffold: - go test ./create/scaffold -ginkgo.v -ginkgo.focus "Scaffold Command Test Suite" + go test ./create/scaffold -ginkgo.v -ginkgo.focus "Test 'Scaffold'" test-module-create: go test ./create/scaffold -ginkgo.v -ginkgo.focus "Module Command Test Suite" From 6babc37f4963f00a8717a3eeb307d5aa30d638ef Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Wed, 4 Sep 2024 09:16:34 +0200 Subject: [PATCH 04/40] test --- .github/workflows/build.yaml | 6 +++--- .github/workflows/test-e2e-module-scaffold.yml | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 18614268..f7cbc7bb 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,4 +1,4 @@ -name: Build modulectl +name: Build modulectl1 on: pull_request: branches: @@ -6,8 +6,8 @@ on: - 'release-**' workflow_dispatch: jobs: - build: - name: Build modulectl + build2: + name: Build modulectl3 runs-on: ubuntu-latest steps: - name: Checkout diff --git a/.github/workflows/test-e2e-module-scaffold.yml b/.github/workflows/test-e2e-module-scaffold.yml index 2ac38ecf..24a53463 100644 --- a/.github/workflows/test-e2e-module-scaffold.yml +++ b/.github/workflows/test-e2e-module-scaffold.yml @@ -1,12 +1,11 @@ -name: "E2E test: modulectl scaffold" +name: "E2E test - modulectl scaffold" on: pull_request: branches: - main - 'release-**' jobs: - e2e-test: - name: E2E test - modulectl scaffold + test: runs-on: ubuntu-latest steps: - name: Checkout From ab16656df9c6efd8b2b727c6ac4ec58c9c7405a6 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Wed, 4 Sep 2024 09:27:47 +0200 Subject: [PATCH 05/40] test --- .github/workflows/build.yaml | 5 ++--- ...{test-e2e-module-create.yml => test-e2e-create.yml} | 8 ++++---- ...t-e2e-module-scaffold.yml => test-e2e-scaffold.yml} | 6 +++--- tests/e2e/Makefile | 10 +++++----- tests/e2e/scaffold/scaffold_test.go | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) rename .github/workflows/{test-e2e-module-create.yml => test-e2e-create.yml} (95%) rename .github/workflows/{test-e2e-module-scaffold.yml => test-e2e-scaffold.yml} (85%) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f7cbc7bb..e82b1bf7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,4 +1,4 @@ -name: Build modulectl1 +name: Build on: pull_request: branches: @@ -6,8 +6,7 @@ on: - 'release-**' workflow_dispatch: jobs: - build2: - name: Build modulectl3 + build-modulectl: runs-on: ubuntu-latest steps: - name: Checkout diff --git a/.github/workflows/test-e2e-module-create.yml b/.github/workflows/test-e2e-create.yml similarity index 95% rename from .github/workflows/test-e2e-module-create.yml rename to .github/workflows/test-e2e-create.yml index 2b837fdb..190d503e 100644 --- a/.github/workflows/test-e2e-module-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -1,4 +1,4 @@ -name: E2E test - module create +name: E2E test - create command on: push: branches: @@ -9,7 +9,7 @@ on: - main - 'release-**' jobs: - e2e: + test-create-cmd: strategy: matrix: e2e-test: [ 'test-module-create', @@ -83,9 +83,9 @@ jobs: if: ${{ matrix.e2e-test == 'test-module-create' }} run: | echo $MODULE_TEMPLATE_PATH - make -C tests/e2e test-module-creation + make -C tests/e2e test-create-cmd - name: Run E2E tests if: ${{ matrix.e2e-test == 'test-module-create-same-version'}} run: | echo $MODULE_TEMPLATE_PATH - make -C tests/e2e test-module-creation-same-version + make -C tests/e2e test-create-cmd-same-version diff --git a/.github/workflows/test-e2e-module-scaffold.yml b/.github/workflows/test-e2e-scaffold.yml similarity index 85% rename from .github/workflows/test-e2e-module-scaffold.yml rename to .github/workflows/test-e2e-scaffold.yml index 24a53463..cb80b104 100644 --- a/.github/workflows/test-e2e-module-scaffold.yml +++ b/.github/workflows/test-e2e-scaffold.yml @@ -1,11 +1,11 @@ -name: "E2E test - modulectl scaffold" +name: E2E test - scaffold command on: pull_request: branches: - main - 'release-**' jobs: - test: + test-scaffold-cmd: runs-on: ubuntu-latest steps: - name: Checkout @@ -24,5 +24,5 @@ jobs: timeout-minutes: 5 - name: Run tests run: | - make -C tests/e2e test-module-scaffold + make -C tests/e2e test-scaffold-cmd timeout-minutes: 3 diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 49dd6b5a..13f62291 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -13,11 +13,11 @@ SHELL = /usr/bin/env bash -o pipefail ##@ E2E Tests -test-module-scaffold: - go test ./create/scaffold -ginkgo.v -ginkgo.focus "Test 'Scaffold'" +test-scaffold-cmd: + go test ./scaffold -ginkgo.v -ginkgo.focus "Test 'scaffold' Command" -test-module-create: - go test ./create/scaffold -ginkgo.v -ginkgo.focus "Module Command Test Suite" +test-create-cmd: + go test ./create -ginkgo.v -ginkgo.focus "Test 'create' Command" test-module-create-same-version: - go test ./create/scaffold -ginkgo.v -ginkgo.focus "Module Command with same version" + go test ./create -ginkgo.v -ginkgo.focus "Module Command with same version" diff --git a/tests/e2e/scaffold/scaffold_test.go b/tests/e2e/scaffold/scaffold_test.go index 674af031..509b5071 100644 --- a/tests/e2e/scaffold/scaffold_test.go +++ b/tests/e2e/scaffold/scaffold_test.go @@ -17,7 +17,7 @@ const ( markerFileData = "test-marker" ) -var _ = Describe("Test 'Scaffold'", Ordered, func() { +var _ = Describe("Test 'scaffold' Command", Ordered, func() { var initialDir string var workDir string From d8a5fde5c72d8fcb66581f9ef6b7dc8cd68e89f5 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 10:22:30 +0200 Subject: [PATCH 06/40] revert renaming fail --- cmd/modulectl/scaffold/cmd.go | 4 +-- tests/e2e/scaffold/scaffold_test.go | 43 ++++++++++++++--------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/cmd/modulectl/scaffold/cmd.go b/cmd/modulectl/scaffold/cmd.go index f0e9c662..4f97c418 100644 --- a/cmd/modulectl/scaffold/cmd.go +++ b/cmd/modulectl/scaffold/cmd.go @@ -24,11 +24,11 @@ var long string //go:embed example.txt var example string -type ScaffoldService interface { +type Service interface { CreateScaffold(opts scaffold.Options) error } -func NewCmd(scaffoldService ScaffoldService) (*cobra.Command, error) { +func NewCmd(scaffoldService Service) (*cobra.Command, error) { if scaffoldService == nil { return nil, fmt.Errorf("%w: scaffoldService must not be nil", commonerrors.ErrInvalidArg) } diff --git a/tests/e2e/scaffold/scaffold_test.go b/tests/e2e/scaffold/scaffold_test.go index 509b5071..31559a6c 100644 --- a/tests/e2e/scaffold/scaffold_test.go +++ b/tests/e2e/scaffold/scaffold_test.go @@ -42,9 +42,9 @@ var _ = Describe("Test 'scaffold' Command", Ordered, func() { BeforeAll(func() { setup() }) AfterAll(func() { teardown() }) - var cmd createScaffoldCmd - It("When `modulectl create scaffold` command is invoked without any args", func() { - cmd = createScaffoldCmd{} + var cmd scaffoldCmd + It("When `modulectl scaffold` command is invoked without any args", func() { + cmd = scaffoldCmd{} }) It("Then the command should succeed", func() { @@ -73,9 +73,9 @@ var _ = Describe("Test 'scaffold' Command", Ordered, func() { }) AfterAll(func() { teardown() }) - var cmd createScaffoldCmd - It("When `modulectl create scaffold` command is invoked without any args", func() { - cmd = createScaffoldCmd{} + var cmd scaffoldCmd + It("When `modulectl scaffold` command is invoked without any args", func() { + cmd = scaffoldCmd{} }) It("Then the command should fail", func() { err := cmd.execute() @@ -96,9 +96,9 @@ var _ = Describe("Test 'scaffold' Command", Ordered, func() { }) AfterAll(func() { teardown() }) - var cmd createScaffoldCmd - It("When `modulectl create scaffold` command is invoked with --overwrite flag", func() { - cmd = createScaffoldCmd{ + var cmd scaffoldCmd + It("When `modulectl scaffold` command is invoked with --overwrite flag", func() { + cmd = scaffoldCmd{ overwrite: true, } }) @@ -126,9 +126,9 @@ var _ = Describe("Test 'scaffold' Command", Ordered, func() { BeforeAll(func() { setup() }) AfterAll(func() { teardown() }) - var cmd createScaffoldCmd - It("When `modulectl create scaffold` command args override defaults", func() { - cmd = createScaffoldCmd{ + var cmd scaffoldCmd + It("When `modulectl scaffold` command args override defaults", func() { + cmd = scaffoldCmd{ moduleName: "github.com/custom/module", moduleVersion: "3.2.1", moduleChannel: "custom", @@ -172,9 +172,9 @@ var _ = Describe("Test 'scaffold' Command", Ordered, func() { }) AfterAll(func() { teardown() }) - var cmd createScaffoldCmd - It("When `modulectl create scaffold` command is invoked with arguments that match existing files names", func() { - cmd = createScaffoldCmd{ + var cmd scaffoldCmd + It("When `modulectl scaffold` command is invoked with arguments that match existing files names", func() { + cmd = scaffoldCmd{ genManifestFlag: "custom-manifest.yaml", genDefaultCRFlag: "custom-default-cr.yaml", genSecurityScannersConfigFlag: "custom-security-scanners-config.yaml", @@ -252,7 +252,7 @@ func resolveWorkingDirectory() string { return scaffoldDir } - scaffoldDir, err := os.MkdirTemp("", "create_scaffold_test") + scaffoldDir, err := os.MkdirTemp("", "scaffold_test") if err != nil { Fail(err.Error()) } @@ -265,7 +265,7 @@ func cleanupWorkingDirectory(path string) { } } -type createScaffoldCmd struct { +type scaffoldCmd struct { moduleName string moduleVersion string moduleChannel string @@ -276,10 +276,10 @@ type createScaffoldCmd struct { overwrite bool } -func (cmd *createScaffoldCmd) execute() error { +func (cmd *scaffoldCmd) execute() error { var command *exec.Cmd - args := []string{"create", "scaffold"} + args := []string{"scaffold"} if cmd.moduleName != "" { args = append(args, "--module-name="+cmd.moduleName) @@ -316,12 +316,12 @@ func (cmd *createScaffoldCmd) execute() error { command = exec.Command("modulectl", args...) cmdOut, err := command.CombinedOutput() if err != nil { - return fmt.Errorf("create scaffold command failed with output: %s and error: %w", cmdOut, err) + return fmt.Errorf("scaffold command failed with output: %s and error: %w", cmdOut, err) } return nil } -func (cmd *createScaffoldCmd) toConfigBuilder() *moduleConfigBuilder { +func (cmd *scaffoldCmd) toConfigBuilder() *moduleConfigBuilder { res := &moduleConfigBuilder{} res.defaults() if cmd.moduleName != "" { @@ -393,7 +393,6 @@ func (mcb *moduleConfigBuilder) defaults() *moduleConfigBuilder { withManifestPath("manifest.yaml") } -// TODO: https://github.com/kyma-project/modulectl/issues/10 // This is a copy of the moduleConfig struct from internal/scaffold/contentprovider/moduleconfig.go // to not make the moduleConfig public just for the sake of testing. // It is expected that the moduleConfig struct will be made public in the future when introducing more commands. From 8d69d27c01cbd5b8c833b0c58d3f6f947da0b590 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 10:29:40 +0200 Subject: [PATCH 07/40] renaming --- cmd/modulectl/create/cmd.go | 12 +++--- cmd/modulectl/create/cmd_test.go | 4 +- cmd/modulectl/scaffold/cmd.go | 10 ++--- cmd/modulectl/scaffold/cmd_test.go | 4 +- internal/service/create/create.go | 2 +- internal/service/scaffold/scaffold.go | 2 +- internal/service/scaffold/scaffold_test.go | 48 +++++++++++----------- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/cmd/modulectl/create/cmd.go b/cmd/modulectl/create/cmd.go index 29bdb7ed..f0dc3969 100644 --- a/cmd/modulectl/create/cmd.go +++ b/cmd/modulectl/create/cmd.go @@ -24,13 +24,13 @@ var long string //go:embed example.txt var example string -type ModuleService interface { - CreateModule(opts create.Options) error +type Service interface { + Run(opts create.Options) error } -func NewCmd(moduleService ModuleService) (*cobra.Command, error) { - if moduleService == nil { - return nil, fmt.Errorf("%w: createService must not be nil", commonerrors.ErrInvalidArg) +func NewCmd(service Service) (*cobra.Command, error) { + if service == nil { + return nil, fmt.Errorf("%w: create Service must not be nil", commonerrors.ErrInvalidArg) } opts := create.Options{} @@ -41,7 +41,7 @@ func NewCmd(moduleService ModuleService) (*cobra.Command, error) { Long: long, Example: example, RunE: func(cmd *cobra.Command, _ []string) error { - return moduleService.CreateModule(opts) + return service.Run(opts) }, } diff --git a/cmd/modulectl/create/cmd_test.go b/cmd/modulectl/create/cmd_test.go index 6e3510d8..c39fe780 100644 --- a/cmd/modulectl/create/cmd_test.go +++ b/cmd/modulectl/create/cmd_test.go @@ -134,7 +134,7 @@ type moduleServiceStub struct { opts create.Options } -func (m *moduleServiceStub) CreateModule(opts create.Options) error { +func (m *moduleServiceStub) Run(opts create.Options) error { m.called = true m.opts = opts return nil @@ -144,6 +144,6 @@ type moduleServiceErrorStub struct{} var errSomeTestError = errors.New("some test error") -func (s *moduleServiceErrorStub) CreateModule(_ create.Options) error { +func (s *moduleServiceErrorStub) Run(_ create.Options) error { return errSomeTestError } diff --git a/cmd/modulectl/scaffold/cmd.go b/cmd/modulectl/scaffold/cmd.go index 4f97c418..2089407e 100644 --- a/cmd/modulectl/scaffold/cmd.go +++ b/cmd/modulectl/scaffold/cmd.go @@ -25,12 +25,12 @@ var long string var example string type Service interface { - CreateScaffold(opts scaffold.Options) error + Run(opts scaffold.Options) error } -func NewCmd(scaffoldService Service) (*cobra.Command, error) { - if scaffoldService == nil { - return nil, fmt.Errorf("%w: scaffoldService must not be nil", commonerrors.ErrInvalidArg) +func NewCmd(service Service) (*cobra.Command, error) { + if service == nil { + return nil, fmt.Errorf("%w: scaffold Service must not be nil", commonerrors.ErrInvalidArg) } opts := scaffold.Options{} @@ -42,7 +42,7 @@ func NewCmd(scaffoldService Service) (*cobra.Command, error) { Example: example, Args: cobra.NoArgs, RunE: func(_ *cobra.Command, _ []string) error { - return scaffoldService.CreateScaffold(opts) + return service.Run(opts) }, } diff --git a/cmd/modulectl/scaffold/cmd_test.go b/cmd/modulectl/scaffold/cmd_test.go index f7826c86..a6695ed7 100644 --- a/cmd/modulectl/scaffold/cmd_test.go +++ b/cmd/modulectl/scaffold/cmd_test.go @@ -143,7 +143,7 @@ type scaffoldServiceStub struct { opts scaffold.Options } -func (s *scaffoldServiceStub) CreateScaffold(opts scaffold.Options) error { +func (s *scaffoldServiceStub) Run(opts scaffold.Options) error { s.called = true s.opts = opts return nil @@ -153,6 +153,6 @@ type scaffoldServiceErrorStub struct{} var errSomeTestError = errors.New("some test error") -func (s *scaffoldServiceErrorStub) CreateScaffold(_ scaffold.Options) error { +func (s *scaffoldServiceErrorStub) Run(_ scaffold.Options) error { return errSomeTestError } diff --git a/internal/service/create/create.go b/internal/service/create/create.go index 467ded8b..163f5c03 100644 --- a/internal/service/create/create.go +++ b/internal/service/create/create.go @@ -12,7 +12,7 @@ func NewService(moduleConfigService ModuleConfigService) (*Service, error) { }, nil } -func (s *Service) CreateModule(opts Options) error { +func (s *Service) Run(opts Options) error { if err := opts.Validate(); err != nil { return err } diff --git a/internal/service/scaffold/scaffold.go b/internal/service/scaffold/scaffold.go index cc60d81a..c30b2d75 100644 --- a/internal/service/scaffold/scaffold.go +++ b/internal/service/scaffold/scaffold.go @@ -55,7 +55,7 @@ func NewService(moduleConfigService ModuleConfigService, }, nil } -func (s *Service) CreateScaffold(opts Options) error { +func (s *Service) Run(opts Options) error { if err := opts.validate(); err != nil { return err } diff --git a/internal/service/scaffold/scaffold_test.go b/internal/service/scaffold/scaffold_test.go index bc02cc90..f73e942d 100644 --- a/internal/service/scaffold/scaffold_test.go +++ b/internal/service/scaffold/scaffold_test.go @@ -67,7 +67,7 @@ func Test_CreateScaffold_ReturnsError_WhenOutIsNil(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withOut(nil).build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.Out") @@ -81,7 +81,7 @@ func Test_CreateScaffold_ReturnsError_WhenDirectoryIsEmpty(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withDirectory("").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.Directory") @@ -95,7 +95,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleConfigFileName("").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleConfigFileName") @@ -109,7 +109,7 @@ func Test_CreateScaffold_ReturnsError_WhenManifestFileIsEmpty(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withManifestFileName("").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ManifestFileName") @@ -123,7 +123,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleNameIsEmpty(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleName("").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleName") @@ -137,7 +137,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleNameIsExceedingLength(t *testing &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleName(testutils.RandomName(256)).build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleName") @@ -152,7 +152,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleNameIsNotMatchingPattern(t *test &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleName(testutils.RandomName(10)).build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleName") @@ -167,7 +167,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleVersionIsEmpty(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleVersion("").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleVersion") @@ -181,7 +181,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleVersionIsInvalid(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleVersion(testutils.RandomName(10)).build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleVersion") @@ -196,7 +196,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleChannelIsEmpty(t *testing.T) { &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleChannel("").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleChannel") @@ -210,7 +210,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleChannelIsExceedingLength(t *test &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleChannel(testutils.RandomName(33)).build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleChannel") @@ -225,7 +225,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleChannelFallsBelowLength(t *testi &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleChannel(testutils.RandomName(2)).build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleChannel") @@ -240,7 +240,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleChannelNotMatchingCharset(t *tes &fileGeneratorErrorStub{}) opts := newScaffoldOptionsBuilder().withModuleChannel("with not allowed chars 123%&").build() - result := svc.CreateScaffold(opts) + result := svc.Run(opts) require.ErrorIs(t, result, commonerrors.ErrInvalidOption) assert.Contains(t, result.Error(), "opts.ModuleChannel") @@ -254,7 +254,7 @@ func Test_CreateScaffold_ReturnsError_WhenModuleConfigServiceForceExplicitOverwr &fileGeneratorErrorStub{}, &fileGeneratorErrorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.ErrorIs(t, result, errOverwriteError) } @@ -266,7 +266,7 @@ func Test_CreateScaffold_ReturnsError_WhenGeneratingManifestFileFails(t *testing &fileGeneratorErrorStub{}, &fileGeneratorErrorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.ErrorIs(t, result, scaffold.ErrGeneratingFile) require.ErrorIs(t, result, errSomeFileGeneratorError) @@ -280,7 +280,7 @@ func Test_CreateScaffold_Succeeds_WhenGeneratingManifestFile(t *testing.T) { &fileGeneratorStub{}, &fileGeneratorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.NoError(t, result) } @@ -292,7 +292,7 @@ func Test_CreateScaffold_Succeeds_WhenDefaultCRFileIsNotConfigured(t *testing.T) &fileGeneratorErrorStub{}, &fileGeneratorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().withDefaultCRFileName("").build()) + result := svc.Run(newScaffoldOptionsBuilder().withDefaultCRFileName("").build()) require.NoError(t, result) } @@ -304,7 +304,7 @@ func Test_CreateScaffold_ReturnsError_WhenGeneratingDefaultCRFileFails(t *testin &fileGeneratorErrorStub{}, &fileGeneratorErrorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.ErrorIs(t, result, scaffold.ErrGeneratingFile) require.ErrorIs(t, result, errSomeFileGeneratorError) @@ -318,7 +318,7 @@ func Test_CreateScaffold_Succeeds_WhenGeneratingDefaultCRFile(t *testing.T) { &fileGeneratorStub{}, &fileGeneratorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.NoError(t, result) } @@ -330,7 +330,7 @@ func Test_CreateScaffold_Succeeds_WhenSecurityConfigFileIsNotConfigured(t *testi &fileGeneratorStub{}, &fileGeneratorErrorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().withSecurityConfigFileName("").build()) + result := svc.Run(newScaffoldOptionsBuilder().withSecurityConfigFileName("").build()) require.NoError(t, result) } @@ -342,7 +342,7 @@ func Test_CreateScaffold_ReturnsError_WhenGeneratingSecurityConfigFileFails(t *t &fileGeneratorStub{}, &fileGeneratorErrorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.ErrorIs(t, result, scaffold.ErrGeneratingFile) require.ErrorIs(t, result, errSomeFileGeneratorError) @@ -356,7 +356,7 @@ func Test_CreateScaffold_Succeeds_WhenGeneratingSecurityConfigFile(t *testing.T) &fileGeneratorStub{}, &fileGeneratorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.NoError(t, result) } @@ -368,7 +368,7 @@ func Test_CreateScaffold_ReturnsError_WhenGeneratingModuleConfigReturnsError(t * &fileGeneratorStub{}, &fileGeneratorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.ErrorIs(t, result, scaffold.ErrGeneratingFile) require.ErrorIs(t, result, errSomeFileGeneratorError) @@ -382,7 +382,7 @@ func Test_CreateScaffold_Succeeds(t *testing.T) { &fileGeneratorStub{}, &fileGeneratorStub{}) - result := svc.CreateScaffold(newScaffoldOptionsBuilder().build()) + result := svc.Run(newScaffoldOptionsBuilder().build()) require.NoError(t, result) } From 6a6fd8703f2f6a23a32e5c6e4969d36ea7d9d14e Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 10:37:35 +0200 Subject: [PATCH 08/40] add unit tests for scaffold options Validate function --- internal/service/scaffold/options.go | 2 +- internal/service/scaffold/options_test.go | 124 ++++++++++++++++++++++ internal/service/scaffold/scaffold.go | 2 +- 3 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 internal/service/scaffold/options_test.go diff --git a/internal/service/scaffold/options.go b/internal/service/scaffold/options.go index fcc00ffb..581cb067 100644 --- a/internal/service/scaffold/options.go +++ b/internal/service/scaffold/options.go @@ -35,7 +35,7 @@ type Options struct { ModuleChannel string } -func (opts Options) validate() error { +func (opts Options) Validate() error { if opts.Out == nil { return fmt.Errorf("%w: opts.Out must not be nil", commonerrors.ErrInvalidOption) } diff --git a/internal/service/scaffold/options_test.go b/internal/service/scaffold/options_test.go new file mode 100644 index 00000000..883add98 --- /dev/null +++ b/internal/service/scaffold/options_test.go @@ -0,0 +1,124 @@ +package scaffold_test + +import ( + "io" + "strings" + "testing" + + "github.com/kyma-project/modulectl/internal/service/scaffold" + iotools "github.com/kyma-project/modulectl/tools/io" + "github.com/stretchr/testify/require" +) + +func Test_Validate_Options(t *testing.T) { + tests := []struct { + name string + options scaffold.Options + wantErr bool + errMsg string + }{ + { + name: "Out is nil", + options: scaffold.Options{Out: nil}, + wantErr: true, + errMsg: "opts.Out must not be nil", + }, + { + name: "ModuleName is empty", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: ""}, + wantErr: true, + errMsg: "opts.ModuleName must not be empty", + }, + { + name: "ModuleName exceeds length", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: strings.Repeat("a", 256)}, + wantErr: true, + errMsg: "opts.ModuleName length must not exceed", + }, + { + name: "ModuleName invalid pattern", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "invalid_name"}, + wantErr: true, + errMsg: "opts.ModuleName must match the required pattern", + }, + { + name: "Directory is empty", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: ""}, + wantErr: true, + errMsg: "opts.Directory must not be empty", + }, + { + name: "ModuleVersion is empty", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: ""}, + wantErr: true, + errMsg: "opts.ModuleVersion must not be empty", + }, + { + name: "ModuleVersion invalid", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "invalid"}, + wantErr: true, + errMsg: "opts.ModuleVersion failed to parse as semantic version", + }, + { + name: "ModuleChannel is empty", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: ""}, + wantErr: true, + errMsg: "opts.ModuleChannel must not be empty", + }, + { + name: "ModuleChannel exceeds length", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: strings.Repeat("a", 33)}, + wantErr: true, + errMsg: "opts.ModuleChannel length must not exceed", + }, + { + name: "ModuleChannel below minimum length", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "aa"}, + wantErr: true, + errMsg: "opts.ModuleChannel length must be at least", + }, + { + name: "ModuleChannel invalid pattern", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "invalid_channel"}, + wantErr: true, + errMsg: "opts.ModuleChannel must match the required pattern", + }, + { + name: "ModuleConfigFileName is empty", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "stable", ModuleConfigFileName: ""}, + wantErr: true, + errMsg: "opts.ModuleConfigFileName must not be empty", + }, + { + name: "ManifestFileName is empty", + options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "stable", ModuleConfigFileName: "config.yaml", ManifestFileName: ""}, + wantErr: true, + errMsg: "opts.ManifestFileName must not be empty", + }, + { + name: "All fields valid", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: "stable", + ModuleConfigFileName: "config.yaml", + ManifestFileName: "manifest.yaml", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.options.Validate() + if tt.wantErr { + require.Error(t, err) + require.Contains(t, err.Error(), tt.errMsg) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/internal/service/scaffold/scaffold.go b/internal/service/scaffold/scaffold.go index c30b2d75..95efc2a1 100644 --- a/internal/service/scaffold/scaffold.go +++ b/internal/service/scaffold/scaffold.go @@ -56,7 +56,7 @@ func NewService(moduleConfigService ModuleConfigService, } func (s *Service) Run(opts Options) error { - if err := opts.validate(); err != nil { + if err := opts.Validate(); err != nil { return err } From c6967c76f78dd452c6577bbd32b5e9281a4a6dd4 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 14:38:00 +0200 Subject: [PATCH 09/40] fix yaml unmarshal of module template --- .github/workflows/test-e2e-create.yml | 7 ++++--- go.mod | 7 +++++-- go.sum | 12 ++++++++++-- tests/e2e/create/create_new_test.go | 1 + tests/e2e/create/create_test.go | 14 +++++++++++--- 5 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 tests/e2e/create/create_new_test.go diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index 190d503e..b9b3bf43 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -59,9 +59,10 @@ jobs: --registry http://k3d-oci.localhost:5001 \ --insecure \ --module-config-file ./module-config.yaml \ - --version $MODULE_TEMPLATE_VERSION -v \ + --version $MODULE_TEMPLATE_VERSION \ --sec-scanners-config sec-scanners-config.yaml \ - --output /tmp/module-config-template.yaml + --output /tmp/module-config-template.yaml \ + --verbose echo "MODULE_TEMPLATE_PATH=/tmp/module-config-template.yaml" >> "$GITHUB_ENV" - name: Create a different security scanners config file for different layers if: ${{matrix.e2e-test == 'test-module-create-same-version' }} @@ -79,7 +80,7 @@ jobs: - \"**/test/**\" - \"**/*_test.go\"" > sec-scanners-config-changed.yaml cat sec-scanners-config-changed.yaml - - name: Verify module template + - name: Verify created module template if: ${{ matrix.e2e-test == 'test-module-create' }} run: | echo $MODULE_TEMPLATE_PATH diff --git a/go.mod b/go.mod index 0ac3cd5a..232bbff8 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22.6 require ( github.com/Masterminds/semver/v3 v3.3.0 - github.com/kyma-project/lifecycle-manager/api v0.0.0-20240903130243-695e809e05b7 + github.com/kyma-project/lifecycle-manager/api v0.0.0-20240905061843-1557b7ab0962 github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 github.com/open-component-model/ocm v0.13.0 @@ -12,6 +12,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 + k8s.io/apimachinery v0.31.0 ) require ( @@ -114,6 +115,7 @@ require ( github.com/elliotchance/orderedmap v1.6.0 // indirect github.com/emicklei/go-restful/v3 v3.11.1 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -297,6 +299,7 @@ require ( golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/api v0.188.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect @@ -310,13 +313,13 @@ require ( helm.sh/helm/v3 v3.15.3 // indirect k8s.io/api v0.31.0 // indirect k8s.io/apiextensions-apiserver v0.31.0 // indirect - k8s.io/apimachinery v0.31.0 // indirect k8s.io/cli-runtime v0.30.3 // indirect k8s.io/client-go v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect oras.land/oras-go v1.2.5 // indirect + sigs.k8s.io/controller-runtime v0.19.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.17.1 // indirect sigs.k8s.io/kustomize/kyaml v0.17.0 // indirect diff --git a/go.sum b/go.sum index 24e98feb..c4149cec 100644 --- a/go.sum +++ b/go.sum @@ -352,6 +352,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -391,6 +393,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= @@ -626,8 +630,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/kyma-project/lifecycle-manager/api v0.0.0-20240903130243-695e809e05b7 h1:WTUspXigXUhzUd5a0JxC73UMCLd5XqoRkGwyt6uE2t8= -github.com/kyma-project/lifecycle-manager/api v0.0.0-20240903130243-695e809e05b7/go.mod h1:bJcxlY2l9sLJmb6ELl/8/p5Nl3EmL2zMPGL329i4uAs= +github.com/kyma-project/lifecycle-manager/api v0.0.0-20240905061843-1557b7ab0962 h1:Pg8hgOjtNp8z6lvyuskozWo9XNtoowJwBucNUq4iMP4= +github.com/kyma-project/lifecycle-manager/api v0.0.0-20240905061843-1557b7ab0962/go.mod h1:bJcxlY2l9sLJmb6ELl/8/p5Nl3EmL2zMPGL329i4uAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ= @@ -1165,6 +1169,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1258,6 +1264,8 @@ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.17.1 h1:MYJBOP/yQ3/5tp4/sf6HiiMfNNyO97LmtnirH9SLNr4= diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go new file mode 100644 index 00000000..ef4f218a --- /dev/null +++ b/tests/e2e/create/create_new_test.go @@ -0,0 +1 @@ +package create diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 47ad6f39..f23819c3 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -6,7 +6,7 @@ import ( "github.com/kyma-project/lifecycle-manager/api/v1beta2" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" - "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/util/yaml" "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" @@ -28,6 +28,12 @@ const ( ) func Test_ModuleTemplate(t *testing.T) { + // TODO remove debugging env + //err := os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") + //err = os.Setenv("TEST_REPOSITORY_URL", "https://github.com/lindnerby/template-operator.git") + //err = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") + //err = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") + ociRepoURL := os.Getenv("OCI_REPOSITORY_URL") testRepoURL := os.Getenv("TEST_REPOSITORY_URL") templatePath := os.Getenv("MODULE_TEMPLATE_PATH") @@ -121,11 +127,13 @@ func Test_ModuleTemplate(t *testing.T) { func readModuleTemplate(filepath string) (*v1beta2.ModuleTemplate, error) { moduleTemplate := &v1beta2.ModuleTemplate{} moduleFile, err := os.ReadFile(filepath) + if err != nil && len(moduleFile) > 0 { + return nil, err + } + err = yaml.Unmarshal(moduleFile, moduleTemplate) if err != nil { return nil, err } - err = yaml.Unmarshal(moduleFile, &moduleTemplate) - return moduleTemplate, err } From 54eac8c1b11f1ea12e71b68fe97863fc0f31f631 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 14:39:10 +0200 Subject: [PATCH 10/40] add new ginkgo format create e2e tests --- tests/e2e/create/create_new_test.go | 415 +++++++++++++++++++++++++++- 1 file changed, 414 insertions(+), 1 deletion(-) diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go index ef4f218a..1d4c8a70 100644 --- a/tests/e2e/create/create_new_test.go +++ b/tests/e2e/create/create_new_test.go @@ -1 +1,414 @@ -package create +package create_test + +import ( + "fmt" + "io/fs" + "os" + "os/exec" + "path" + + "gopkg.in/yaml.v3" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + markerFileData = "test-marker" +) + +var _ = Describe("Test 'create' Command", Ordered, func() { + var initialDir string + var workDir string + + setup := func() { + var err error + initialDir, err = os.Getwd() + Expect(err).ToNot(HaveOccurred()) + workDir = resolveWorkingDirectory() + err = os.Chdir(workDir) + Expect(err).ToNot(HaveOccurred()) + } + + teardown := func() { + err := os.Chdir(initialDir) + Expect(err).ToNot(HaveOccurred()) + cleanupWorkingDirectory(workDir) + workDir = "" + initialDir = "" + } + + Context("Given an empty directory", func() { + BeforeAll(func() { setup() }) + AfterAll(func() { teardown() }) + + var cmd createCmd + It("When `modulectl create` command is invoked without any args", func() { + cmd = createCmd{} + }) + + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And two files are generated") + Expect(filesIn(workDir)).Should(HaveLen(2)) + + By("And the manifest file is generated") + Expect(filesIn(workDir)).Should(ContainElement("manifest.yaml")) + + By("And the module config file is generated") + Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) + + By("And the module config contains expected entries") + actualModConf := moduleConfigFromFile(workDir, "create-module-config.yaml") + expectedModConf := (&moduleConfigBuilder{}).defaults().get() + Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + }) + }) + + Context("Given a directory with an existing module configuration file", func() { + BeforeAll(func() { + setup() + Expect(createMarkerFile("create-module-config.yaml")).To(Succeed()) + }) + AfterAll(func() { teardown() }) + + var cmd createCmd + It("When `modulectl create` command is invoked without any args", func() { + cmd = createCmd{} + }) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("module config file already exists")) + + By("And no files should be generated") + Expect(filesIn(workDir)).Should(HaveLen(1)) + Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) + Expect(getMarkerFileData("create-module-config.yaml")).Should(Equal(markerFileData)) + }) + }) + + Context("Given a directory with an existing module configuration file", func() { + BeforeAll(func() { + setup() + Expect(createMarkerFile("create-module-config.yaml")).To(Succeed()) + }) + AfterAll(func() { teardown() }) + + var cmd createCmd + It("When `modulectl create` command is invoked with --overwrite flag", func() { + cmd = createCmd{ + overwrite: true, + } + }) + + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And two files are generated") + Expect(filesIn(workDir)).Should(HaveLen(2)) + + By("And the manifest file is generated") + Expect(filesIn(workDir)).Should(ContainElement("manifest.yaml")) + + By("And the module config file is generated") + Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) + + By("And the module config contains expected entries") + actualModConf := moduleConfigFromFile(workDir, "create-module-config.yaml") + expectedModConf := (&moduleConfigBuilder{}).defaults().get() + Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + }) + }) + + Context("Given an empty directory", func() { + BeforeAll(func() { setup() }) + AfterAll(func() { teardown() }) + + var cmd createCmd + It("When `modulectl create` command args override defaults", func() { + cmd = createCmd{ + moduleName: "github.com/custom/module", + moduleVersion: "3.2.1", + moduleChannel: "custom", + moduleConfigFileFlag: "custom-module-config.yaml", + genManifestFlag: "custom-manifest.yaml", + genDefaultCRFlag: "custom-default-cr.yaml", + genSecurityScannersConfigFlag: "custom-security-scanners-config.yaml", + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And four files are generated") + Expect(filesIn(workDir)).Should(HaveLen(4)) + + By("And the manifest file is generated") + Expect(filesIn(workDir)).Should(ContainElement("custom-manifest.yaml")) + + By("And the defaultCR file is generated") + Expect(filesIn(workDir)).Should(ContainElement("custom-default-cr.yaml")) + + By("And the security-scanners-config file is generated") + Expect(filesIn(workDir)).Should(ContainElement("custom-security-scanners-config.yaml")) + + By("And the module config file is generated") + Expect(filesIn(workDir)).Should(ContainElement("custom-module-config.yaml")) + + By("And the module config contains expected entries") + actualModConf := moduleConfigFromFile(workDir, "custom-module-config.yaml") + expectedModConf := cmd.toConfigBuilder().get() + Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + }) + }) + + Context("Given a directory with existing files", func() { + BeforeAll(func() { + setup() + Expect(createMarkerFile("custom-manifest.yaml")).To(Succeed()) + Expect(createMarkerFile("custom-default-cr.yaml")).To(Succeed()) + Expect(createMarkerFile("custom-security-scanners-config.yaml")).To(Succeed()) + }) + AfterAll(func() { teardown() }) + + var cmd createCmd + It("When `modulectl create` command is invoked with arguments that match existing files names", func() { + cmd = createCmd{ + genManifestFlag: "custom-manifest.yaml", + genDefaultCRFlag: "custom-default-cr.yaml", + genSecurityScannersConfigFlag: "custom-security-scanners-config.yaml", + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And there should be four files in the directory") + Expect(filesIn(workDir)).Should(HaveLen(4)) + + By("And the manifest file is reused (not generated)") + Expect(getMarkerFileData("custom-manifest.yaml")).Should(Equal(markerFileData)) + + By("And the defaultCR file is reused (not generated)") + Expect(getMarkerFileData("custom-default-cr.yaml")).Should(Equal(markerFileData)) + + By("And the security-scanners-config file is reused (not generated)") + Expect(getMarkerFileData("custom-security-scanners-config.yaml")).Should(Equal(markerFileData)) + + By("And the module config file is generated") + Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) + + By("And module config contains expected entries") + actualModConf := moduleConfigFromFile(workDir, "create-module-config.yaml") + expectedModConf := cmd.toConfigBuilder().get() + Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + }) + }) +}) + +func getMarkerFileData(name string) string { + data, err := os.ReadFile(name) + Expect(err).ToNot(HaveOccurred()) + return string(data) +} + +func createMarkerFile(name string) error { + err := os.WriteFile(name, []byte(markerFileData), 0o600) + return err +} + +func moduleConfigFromFile(dir, fileName string) *moduleConfig { + filePath := path.Join(dir, fileName) + data, err := os.ReadFile(filePath) + Expect(err).ToNot(HaveOccurred()) + res := moduleConfig{} + err = yaml.Unmarshal(data, &res) + Expect(err).ToNot(HaveOccurred()) + return &res +} + +func filesIn(dir string) []string { + fi, err := os.Stat(dir) + Expect(err).ToNot(HaveOccurred()) + Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) + + dirFs := os.DirFS(dir) + entries, err := fs.ReadDir(dirFs, ".") + Expect(err).ToNot(HaveOccurred()) + + var res []string + for _, ent := range entries { + if ent.Type().IsRegular() { + res = append(res, ent.Name()) + } + } + + return res +} + +func resolveWorkingDirectory() string { + createDir := os.Getenv("CREATE_DIR") + if len(createDir) > 0 { + return createDir + } + + createDir, err := os.MkdirTemp("", "create_test") + if err != nil { + Fail(err.Error()) + } + return createDir +} + +func cleanupWorkingDirectory(path string) { + if len(os.Getenv("CREATE_DIR")) == 0 { + _ = os.RemoveAll(path) + } +} + +type createCmd struct { + moduleName string + moduleVersion string + moduleChannel string + moduleConfigFileFlag string + genDefaultCRFlag string + genSecurityScannersConfigFlag string + genManifestFlag string + overwrite bool +} + +func (cmd *createCmd) execute() error { + var command *exec.Cmd + + args := []string{"create"} + + if cmd.moduleName != "" { + args = append(args, "--module-name="+cmd.moduleName) + } + + if cmd.moduleVersion != "" { + args = append(args, "--module-version="+cmd.moduleVersion) + } + + if cmd.moduleChannel != "" { + args = append(args, "--module-channel="+cmd.moduleChannel) + } + + if cmd.moduleConfigFileFlag != "" { + args = append(args, "--module-config="+cmd.moduleConfigFileFlag) + } + + if cmd.genDefaultCRFlag != "" { + args = append(args, "--gen-default-cr="+cmd.genDefaultCRFlag) + } + + if cmd.genSecurityScannersConfigFlag != "" { + args = append(args, "--gen-security-config="+cmd.genSecurityScannersConfigFlag) + } + + if cmd.genManifestFlag != "" { + args = append(args, "--gen-manifest="+cmd.genManifestFlag) + } + + if cmd.overwrite { + args = append(args, "--overwrite=true") + } + + command = exec.Command("modulectl", args...) + cmdOut, err := command.CombinedOutput() + if err != nil { + return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) + } + return nil +} + +func (cmd *createCmd) toConfigBuilder() *moduleConfigBuilder { + res := &moduleConfigBuilder{} + res.defaults() + if cmd.moduleName != "" { + res.withName(cmd.moduleName) + } + if cmd.moduleVersion != "" { + res.withVersion(cmd.moduleVersion) + } + if cmd.moduleChannel != "" { + res.withChannel(cmd.moduleChannel) + } + if cmd.genDefaultCRFlag != "" { + res.withDefaultCRPath(cmd.genDefaultCRFlag) + } + if cmd.genSecurityScannersConfigFlag != "" { + res.withSecurityScannersPath(cmd.genSecurityScannersConfigFlag) + } + if cmd.genManifestFlag != "" { + res.withManifestPath(cmd.genManifestFlag) + } + return res +} + +// moduleConfigBuilder is used to simplify module.Config creation for testing purposes +type moduleConfigBuilder struct { + moduleConfig +} + +func (mcb *moduleConfigBuilder) get() *moduleConfig { + res := mcb.moduleConfig + return &res +} + +func (mcb *moduleConfigBuilder) withName(val string) *moduleConfigBuilder { + mcb.Name = val + return mcb +} + +func (mcb *moduleConfigBuilder) withVersion(val string) *moduleConfigBuilder { + mcb.Version = val + return mcb +} + +func (mcb *moduleConfigBuilder) withChannel(val string) *moduleConfigBuilder { + mcb.Channel = val + return mcb +} + +func (mcb *moduleConfigBuilder) withManifestPath(val string) *moduleConfigBuilder { + mcb.ManifestPath = val + return mcb +} + +func (mcb *moduleConfigBuilder) withDefaultCRPath(val string) *moduleConfigBuilder { + mcb.DefaultCRPath = val + return mcb +} + +func (mcb *moduleConfigBuilder) withSecurityScannersPath(val string) *moduleConfigBuilder { + mcb.Security = val + return mcb +} + +func (mcb *moduleConfigBuilder) defaults() *moduleConfigBuilder { + return mcb. + withName("kyma-project.io/module/mymodule"). + withVersion("0.0.1"). + withChannel("regular"). + withManifestPath("manifest.yaml") +} + +// This is a copy of the moduleConfig struct from internal/create/contentprovider/moduleconfig.go +// to not make the moduleConfig public just for the sake of testing. +// It is expected that the moduleConfig struct will be made public in the future when introducing more commands. +// Once it is public, this struct should be removed. +type moduleConfig struct { + Name string `yaml:"name" comment:"required, the name of the Module"` + Version string `yaml:"version" comment:"required, the version of the Module"` + Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"` + ManifestPath string `yaml:"manifest" comment:"required, relative path or remote URL to the manifests"` + Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"` + DefaultCRPath string `yaml:"defaultCR" comment:"optional, relative path or remote URL to a YAML file containing the default CR for the module"` + ResourceName string `yaml:"resourceName" comment:"optional, default={name}-{channel}, when channel is 'none', the default is {name}-{version}, the name for the ModuleTemplate that will be created"` + Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"` + Security string `yaml:"security" comment:"optional, name of the security scanners config file"` + Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"` + Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"` + Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"` + Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"` +} From f7d29358be50091f3e775e3876203696678c5f0e Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 14:44:07 +0200 Subject: [PATCH 11/40] lint --- internal/service/scaffold/options_test.go | 3 ++- tests/e2e/create/create_same_ver_test.go | 6 +++--- tests/e2e/create/create_test.go | 24 +++++++++++------------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/internal/service/scaffold/options_test.go b/internal/service/scaffold/options_test.go index 883add98..ca34be75 100644 --- a/internal/service/scaffold/options_test.go +++ b/internal/service/scaffold/options_test.go @@ -5,9 +5,10 @@ import ( "strings" "testing" - "github.com/kyma-project/modulectl/internal/service/scaffold" iotools "github.com/kyma-project/modulectl/tools/io" "github.com/stretchr/testify/require" + + "github.com/kyma-project/modulectl/internal/service/scaffold" ) func Test_Validate_Options(t *testing.T) { diff --git a/tests/e2e/create/create_same_ver_test.go b/tests/e2e/create/create_same_ver_test.go index 853f452a..51494edb 100644 --- a/tests/e2e/create/create_same_ver_test.go +++ b/tests/e2e/create/create_same_ver_test.go @@ -29,13 +29,13 @@ func Test_SameVersion_ModuleCreation(t *testing.T) { t.Run("Create same version module with module-archive-version-overwrite flag", func(t *testing.T) { err := createModuleCommand(true, path, registry, configFilePath, version, secScannerConfigFile) - assert.Nil(t, err) + assert.NoError(t, err) }) t.Run("Create same version module and same content without module-archive-version-overwrite flag", func(t *testing.T) { err := createModuleCommand(false, path, registry, configFilePath, version, secScannerConfigFile) - assert.Nil(t, err) + assert.NoError(t, err) }) t.Run("Create same version module, but different content without module-archive-version-overwrite flag", @@ -64,7 +64,7 @@ func createModuleCommand(versionOverwrite bool, fmt.Sprintf("version %s already exists with different content", version)) { return errCreateModuleFailedWithSameVersion } - return fmt.Errorf("create module command failed with err %s", err) + return fmt.Errorf("create module command failed: %w", err) } return nil } diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index f23819c3..4a1fc25f 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -4,22 +4,20 @@ import ( "os" "testing" - "github.com/kyma-project/lifecycle-manager/api/v1beta2" - "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" - "k8s.io/apimachinery/pkg/util/yaml" - "github.com/kyma-project/lifecycle-manager/api/shared" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" - + "github.com/kyma-project/lifecycle-manager/api/v1beta2" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" ocmMetaV1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" v2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" ocmOCIReg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/util/yaml" ) const ( @@ -29,10 +27,10 @@ const ( func Test_ModuleTemplate(t *testing.T) { // TODO remove debugging env - //err := os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") - //err = os.Setenv("TEST_REPOSITORY_URL", "https://github.com/lindnerby/template-operator.git") - //err = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") - //err = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") + // err := os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") + // err = os.Setenv("TEST_REPOSITORY_URL", "https://github.com/lindnerby/template-operator.git") + // err = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") + // err = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") ociRepoURL := os.Getenv("OCI_REPOSITORY_URL") testRepoURL := os.Getenv("TEST_REPOSITORY_URL") @@ -78,7 +76,7 @@ func Test_ModuleTemplate(t *testing.T) { t.Run("test descriptor.component.resources[0].access", func(t *testing.T) { resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) - assert.Nil(t, err) + assert.NoError(t, err) ociArtifactAccessSpec, ok := resourceAccessSpec.(*ociartifact.AccessSpec) assert.True(t, ok) assert.Equal(t, ociartifact.Type, ociArtifactAccessSpec.GetType()) @@ -88,7 +86,7 @@ func Test_ModuleTemplate(t *testing.T) { t.Run("test descriptor.component.resources[1].access", func(t *testing.T) { resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) - assert.Nil(t, err) + assert.NoError(t, err) localBlobAccessSpec, ok := resourceAccessSpec.(*localblob.AccessSpec) assert.True(t, ok) assert.Equal(t, localblob.Type, localBlobAccessSpec.GetType()) @@ -99,7 +97,7 @@ func Test_ModuleTemplate(t *testing.T) { assert.Equal(t, len(descriptor.Sources), 1) source := descriptor.Sources[0] sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) - assert.Nil(t, err) + assert.NoError(t, err) githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) assert.True(t, ok) assert.Equal(t, github.Type, githubAccessSpec.Type) From 1520aa496733e6aa05fddf987e9ed14c61435a4e Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 15:02:34 +0200 Subject: [PATCH 12/40] fix linter but keep todo to fail --- .golangci.yaml | 9 ++++-- internal/service/scaffold/options_test.go | 2 +- tests/e2e/create/create_test.go | 34 +++++++++++------------ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 7f672cf4..d97c6efb 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -6,7 +6,7 @@ linters: - exhaustruct # too subjective and harms code readability - execinquery # deprecated (since v1.58.0) - exportloopref # deprecated (since v1.60.2), replaced by copyloopvar - - forbidigo # temparily disabled + - forbidigo # temporarily disabled - godot # not needed - gomnd # deprecated (since v1.58.0), renamed to mnd - lll @@ -58,6 +58,12 @@ linters-settings: alias: scaffoldcmd - pkg: github.com/kyma-project/modulectl/cmd/modulectl/create alias: createcmd + - pkg: github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1 + alias: ocmmetav1 + - pkg: github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2 + alias: compdescv2 + - pkg: github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg + alias: ocmocireg ireturn: allow: - anon @@ -70,7 +76,6 @@ linters-settings: ignore-type-assert-ok: true ignore-map-index-ok: true ignore-chan-recv-ok: true - godox: # `TODO`, `BUG`, `FIXME` are the default, no need to mention again issues: exclude-rules: - path: "_test\\.go" diff --git a/internal/service/scaffold/options_test.go b/internal/service/scaffold/options_test.go index ca34be75..89c6080a 100644 --- a/internal/service/scaffold/options_test.go +++ b/internal/service/scaffold/options_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" - iotools "github.com/kyma-project/modulectl/tools/io" "github.com/stretchr/testify/require" "github.com/kyma-project/modulectl/internal/service/scaffold" + iotools "github.com/kyma-project/modulectl/tools/io" ) func Test_Validate_Options(t *testing.T) { diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 4a1fc25f..174adceb 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -12,11 +12,11 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" - ocmMetaV1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" - v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" - v2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" - ocmOCIReg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" + ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" + ocmocireg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/util/yaml" ) @@ -37,10 +37,10 @@ func Test_ModuleTemplate(t *testing.T) { templatePath := os.Getenv("MODULE_TEMPLATE_PATH") template, err := readModuleTemplate(templatePath) - assert.Nil(t, err) + require.NoError(t, err) descriptor := getDescriptor(template) assert.NotNil(t, descriptor) - assert.Equal(t, descriptor.SchemaVersion(), v2.SchemaVersion) + assert.Equal(t, compdescv2.SchemaVersion, descriptor.SchemaVersion()) t.Run("test annotations", func(t *testing.T) { annotations := template.Annotations @@ -50,33 +50,33 @@ func Test_ModuleTemplate(t *testing.T) { }) t.Run("test descriptor.component.repositoryContexts", func(t *testing.T) { - assert.Equal(t, 1, len(descriptor.RepositoryContexts)) + assert.Len(t, 1, len(descriptor.RepositoryContexts)) repo := descriptor.GetEffectiveRepositoryContext() assert.Equal(t, ociRepoURL, repo.Object["baseUrl"]) - assert.Equal(t, string(ocmOCIReg.OCIRegistryURLPathMapping), repo.Object["componentNameMapping"]) + assert.Equal(t, string(ocmocireg.OCIRegistryURLPathMapping), repo.Object["componentNameMapping"]) assert.Equal(t, ocireg.Type, repo.Object["type"]) }) t.Run("test descriptor.component.resources", func(t *testing.T) { - assert.Equal(t, 2, len(descriptor.Resources)) + assert.Len(t, 2, len(descriptor.Resources)) resource := descriptor.Resources[0] assert.Equal(t, "template-operator", resource.Name) - assert.Equal(t, ocmMetaV1.ExternalRelation, resource.Relation) + assert.Equal(t, ocmmetav1.ExternalRelation, resource.Relation) assert.Equal(t, "ociImage", resource.Type) expectedModuleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") assert.Equal(t, expectedModuleTemplateVersion, resource.Version) resource = descriptor.Resources[1] assert.Equal(t, rawManifestLayerName, resource.Name) - assert.Equal(t, ocmMetaV1.LocalRelation, resource.Relation) + assert.Equal(t, ocmmetav1.LocalRelation, resource.Relation) assert.Equal(t, typeYaml, resource.Type) assert.Equal(t, expectedModuleTemplateVersion, resource.Version) }) t.Run("test descriptor.component.resources[0].access", func(t *testing.T) { resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) - assert.NoError(t, err) + require.NoError(t, err) ociArtifactAccessSpec, ok := resourceAccessSpec.(*ociartifact.AccessSpec) assert.True(t, ok) assert.Equal(t, ociartifact.Type, ociArtifactAccessSpec.GetType()) @@ -86,7 +86,7 @@ func Test_ModuleTemplate(t *testing.T) { t.Run("test descriptor.component.resources[1].access", func(t *testing.T) { resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) - assert.NoError(t, err) + require.NoError(t, err) localBlobAccessSpec, ok := resourceAccessSpec.(*localblob.AccessSpec) assert.True(t, ok) assert.Equal(t, localblob.Type, localBlobAccessSpec.GetType()) @@ -94,10 +94,10 @@ func Test_ModuleTemplate(t *testing.T) { }) t.Run("test descriptor.component.sources", func(t *testing.T) { - assert.Equal(t, len(descriptor.Sources), 1) + assert.Len(t, len(descriptor.Sources), 1) source := descriptor.Sources[0] sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) - assert.NoError(t, err) + require.NoError(t, err) githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) assert.True(t, ok) assert.Equal(t, github.Type, githubAccessSpec.Type) @@ -105,7 +105,7 @@ func Test_ModuleTemplate(t *testing.T) { }) t.Run("test spec.mandatory", func(t *testing.T) { - assert.Equal(t, false, template.Spec.Mandatory) + assert.False(t, template.Spec.Mandatory) }) t.Run("test security scan labels", func(t *testing.T) { @@ -158,7 +158,7 @@ func getDescriptor(template *v1beta2.ModuleTemplate) *v1beta2.Descriptor { return desc } -func flatten(labels v1.Labels) map[string]string { +func flatten(labels ocmmetav1.Labels) map[string]string { labelsMap := make(map[string]string) for _, l := range labels { var value string From 4019928bf71e28498ad0ab44f7ef73804319051c Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 15:16:30 +0200 Subject: [PATCH 13/40] fix unit tests --- cmd/modulectl/create/cmd_test.go | 2 +- cmd/modulectl/scaffold/cmd_test.go | 2 +- tests/e2e/create/create_new_test.go | 2 ++ tests/e2e/create/create_same_ver_test.go | 2 ++ tests/e2e/create/create_suite_test.go | 2 ++ tests/e2e/create/create_test.go | 2 ++ tests/e2e/scaffold/scaffold_suite_test.go | 2 ++ tests/e2e/scaffold/scaffold_test.go | 2 ++ 8 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/modulectl/create/cmd_test.go b/cmd/modulectl/create/cmd_test.go index c39fe780..2ab44fde 100644 --- a/cmd/modulectl/create/cmd_test.go +++ b/cmd/modulectl/create/cmd_test.go @@ -18,7 +18,7 @@ func Test_NewCmd_ReturnsError_WhenModuleServiceIsNil(t *testing.T) { _, err := createcmd.NewCmd(nil) require.Error(t, err) - assert.Contains(t, err.Error(), "createService") + assert.Contains(t, err.Error(), "create Service") } func Test_NewCmd_Succeeds(t *testing.T) { diff --git a/cmd/modulectl/scaffold/cmd_test.go b/cmd/modulectl/scaffold/cmd_test.go index a6695ed7..e72939d6 100644 --- a/cmd/modulectl/scaffold/cmd_test.go +++ b/cmd/modulectl/scaffold/cmd_test.go @@ -17,7 +17,7 @@ func Test_NewCmd_ReturnsError_WhenScaffoldServiceIsNil(t *testing.T) { _, err := scaffoldcmd.NewCmd(nil) require.Error(t, err) - assert.Contains(t, err.Error(), "scaffoldService") + assert.Contains(t, err.Error(), "scaffold Service") } func Test_NewCmd_Succceeds(t *testing.T) { diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go index 1d4c8a70..b7487e0d 100644 --- a/tests/e2e/create/create_new_test.go +++ b/tests/e2e/create/create_new_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package create_test import ( diff --git a/tests/e2e/create/create_same_ver_test.go b/tests/e2e/create/create_same_ver_test.go index 51494edb..500dafed 100644 --- a/tests/e2e/create/create_same_ver_test.go +++ b/tests/e2e/create/create_same_ver_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package create_test import ( diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index 26bf8467..f03b0fb2 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package create_test import ( diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 174adceb..a0394edc 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package create_test import ( diff --git a/tests/e2e/scaffold/scaffold_suite_test.go b/tests/e2e/scaffold/scaffold_suite_test.go index 4d6773cf..44b5bb89 100644 --- a/tests/e2e/scaffold/scaffold_suite_test.go +++ b/tests/e2e/scaffold/scaffold_suite_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package scaffold_test import ( diff --git a/tests/e2e/scaffold/scaffold_test.go b/tests/e2e/scaffold/scaffold_test.go index 31559a6c..20714297 100644 --- a/tests/e2e/scaffold/scaffold_test.go +++ b/tests/e2e/scaffold/scaffold_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package scaffold_test import ( From 493f9c6d64a5913469ae53b056ec9fb712bcceb6 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 15:18:38 +0200 Subject: [PATCH 14/40] use build tags for e2e tests --- tests/e2e/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 13f62291..6ffc2710 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -14,10 +14,10 @@ SHELL = /usr/bin/env bash -o pipefail ##@ E2E Tests test-scaffold-cmd: - go test ./scaffold -ginkgo.v -ginkgo.focus "Test 'scaffold' Command" + go test -tags=e2e ./scaffold -ginkgo.v -ginkgo.focus "Test 'scaffold' Command" test-create-cmd: - go test ./create -ginkgo.v -ginkgo.focus "Test 'create' Command" + go test -tags=e2e ./create -ginkgo.v -ginkgo.focus "Test 'create' Command" test-module-create-same-version: - go test ./create -ginkgo.v -ginkgo.focus "Module Command with same version" + go test -tags=e2e ./create -ginkgo.v -ginkgo.focus "Module Command with same version" From 1cda31bc5e74cefd679b5d873090ad71aff46179 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 5 Sep 2024 15:47:19 +0200 Subject: [PATCH 15/40] test new e2e structure against kyma bin --- tests/e2e/create/create_new_test.go | 30 +++++++++-------------- tests/e2e/create/create_suite_test.go | 2 +- tests/e2e/scaffold/scaffold_suite_test.go | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go index b7487e0d..af241f19 100644 --- a/tests/e2e/create/create_new_test.go +++ b/tests/e2e/create/create_new_test.go @@ -49,22 +49,13 @@ var _ = Describe("Test 'create' Command", Ordered, func() { cmd = createCmd{} }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And two files are generated") - Expect(filesIn(workDir)).Should(HaveLen(2)) - - By("And the manifest file is generated") - Expect(filesIn(workDir)).Should(ContainElement("manifest.yaml")) - - By("And the module config file is generated") - Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - By("And the module config contains expected entries") - actualModConf := moduleConfigFromFile(workDir, "create-module-config.yaml") - expectedModConf := (&moduleConfigBuilder{}).defaults().get() - Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + By("And no files are generated") + Expect(filesIn(workDir)).Should(BeEmpty()) }) }) @@ -76,10 +67,10 @@ var _ = Describe("Test 'create' Command", Ordered, func() { AfterAll(func() { teardown() }) var cmd createCmd - It("When `modulectl create` command is invoked without any args", func() { + It("When `modulectl create` command is invoked with --module-config-file flag", func() { cmd = createCmd{} }) - It("Then the command should fail", func() { + It("Then the command should succeed", func() { err := cmd.execute() Expect(err).Should(HaveOccurred()) Expect(err.Error()).Should(ContainSubstring("module config file already exists")) @@ -281,7 +272,8 @@ type createCmd struct { func (cmd *createCmd) execute() error { var command *exec.Cmd - args := []string{"create"} + // TODO revert to modulectl only debugging against kyma cli bin for verifying tests + args := []string{"alpha", "create", "module"} if cmd.moduleName != "" { args = append(args, "--module-name="+cmd.moduleName) @@ -315,7 +307,7 @@ func (cmd *createCmd) execute() error { args = append(args, "--overwrite=true") } - command = exec.Command("modulectl", args...) + command = exec.Command("kyma", args...) cmdOut, err := command.CombinedOutput() if err != nil { return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index f03b0fb2..d1b728ac 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/gomega" ) -func TestModuleCreate(t *testing.T) { +func Test_Create(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "'Create' Command Test Suite") } diff --git a/tests/e2e/scaffold/scaffold_suite_test.go b/tests/e2e/scaffold/scaffold_suite_test.go index 44b5bb89..cf65da6c 100644 --- a/tests/e2e/scaffold/scaffold_suite_test.go +++ b/tests/e2e/scaffold/scaffold_suite_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/gomega" ) -func TestCreateScaffold(t *testing.T) { +func Test_Scaffold(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "'Scaffold' Command Test Suite") } From f96574b96639ca0d684500f1950f42759608731e Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 10 Sep 2024 08:23:00 +0200 Subject: [PATCH 16/40] stash --- .github/workflows/test-e2e-create.yml | 7 +- .gitignore | 3 + tests/e2e/create/create_new_test.go | 374 ++------------------------ tests/e2e/create/create_suite_test.go | 86 ++++++ 4 files changed, 117 insertions(+), 353 deletions(-) diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index b9b3bf43..54b08466 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -40,11 +40,14 @@ jobs: with: repository: kyma-project/template-operator path: ./template-operator/ - - name: export template-operator URL + - name: Copy template-operator to e2e folder + run: | + cp -r ./template-operator/* ./tests/e2e/create/ + - name: Set template-operator github URL run: | cd ./template-operator echo "TEST_REPOSITORY_URL=$(git remote get-url origin)" >> "$GITHUB_ENV" - - name: Set up k3d + - name: Install k3d run: wget -qO - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=$K3D_VERSION bash - name: Provision OCI Registry run: | diff --git a/.gitignore b/.gitignore index deab2fdc..8fa66441 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,6 @@ bin # rendered manifest **/manifest.yaml + +# copied template-operator repo +tests/e2e/create/testdata/template-operator diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go index af241f19..1b1d9288 100644 --- a/tests/e2e/create/create_new_test.go +++ b/tests/e2e/create/create_new_test.go @@ -3,26 +3,24 @@ package create_test import ( - "fmt" - "io/fs" "os" - "os/exec" - "path" - - "gopkg.in/yaml.v3" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) -const ( - markerFileData = "test-marker" -) - var _ = Describe("Test 'create' Command", Ordered, func() { var initialDir string var workDir string + // TODO adapt path for checked out repo on pipeline + moduleRepoPath := "../../../../template-operator" + configFilePath := "../../../../template-operator/module-config.yaml" + //secScannerConfigFile := "../../../../template-operator/sec-scanners-config.yaml" + // + //changedSecScannerConfigFile := "../../../../template-operator/sec-scanners-config-changed.yaml" + + // TODO see if we can use elegant dir reference to template-operator setup := func() { var err error initialDir, err = os.Getwd() @@ -40,369 +38,43 @@ var _ = Describe("Test 'create' Command", Ordered, func() { initialDir = "" } - Context("Given an empty directory", func() { - BeforeAll(func() { setup() }) - AfterAll(func() { teardown() }) - + Context("Given `modulectl create` command", func() { var cmd createCmd - It("When `modulectl create` command is invoked without any args", func() { + It("When invoked without any args", func() { + //print current dir + currDir, _ := os.Getwd() + By("Current dir: " + currDir) cmd = createCmd{} }) It("Then the command should fail", func() { - err := cmd.execute() - Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - - By("And no files are generated") - Expect(filesIn(workDir)).Should(BeEmpty()) - }) - }) - - Context("Given a directory with an existing module configuration file", func() { - BeforeAll(func() { - setup() - Expect(createMarkerFile("create-module-config.yaml")).To(Succeed()) - }) - AfterAll(func() { teardown() }) - - var cmd createCmd - It("When `modulectl create` command is invoked with --module-config-file flag", func() { cmd = createCmd{} - }) - It("Then the command should succeed", func() { err := cmd.execute() Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("module config file already exists")) - - By("And no files should be generated") - Expect(filesIn(workDir)).Should(HaveLen(1)) - Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) - Expect(getMarkerFileData("create-module-config.yaml")).Should(Equal(markerFileData)) - }) - }) - - Context("Given a directory with an existing module configuration file", func() { - BeforeAll(func() { - setup() - Expect(createMarkerFile("create-module-config.yaml")).To(Succeed()) - }) - AfterAll(func() { teardown() }) - - var cmd createCmd - It("When `modulectl create` command is invoked with --overwrite flag", func() { - cmd = createCmd{ - overwrite: true, - } - }) - - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And two files are generated") - Expect(filesIn(workDir)).Should(HaveLen(2)) - - By("And the manifest file is generated") - Expect(filesIn(workDir)).Should(ContainElement("manifest.yaml")) - - By("And the module config file is generated") - Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) + Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - By("And the module config contains expected entries") - actualModConf := moduleConfigFromFile(workDir, "create-module-config.yaml") - expectedModConf := (&moduleConfigBuilder{}).defaults().get() - Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + //By("And no files are generated") + //Expect(filesIn(workDir)).Should(BeEmpty()) }) }) - Context("Given an empty directory", func() { + Context("Given `modulectl create` command", func() { BeforeAll(func() { setup() }) AfterAll(func() { teardown() }) var cmd createCmd - It("When `modulectl create` command args override defaults", func() { + It("When invoked with --module-config-file and --path", func() { cmd = createCmd{ - moduleName: "github.com/custom/module", - moduleVersion: "3.2.1", - moduleChannel: "custom", - moduleConfigFileFlag: "custom-module-config.yaml", - genManifestFlag: "custom-manifest.yaml", - genDefaultCRFlag: "custom-default-cr.yaml", - genSecurityScannersConfigFlag: "custom-security-scanners-config.yaml", + moduleConfigFile: configFilePath, + path: moduleRepoPath, } }) It("Then the command should succeed", func() { Expect(cmd.execute()).To(Succeed()) - By("And four files are generated") - Expect(filesIn(workDir)).Should(HaveLen(4)) - - By("And the manifest file is generated") - Expect(filesIn(workDir)).Should(ContainElement("custom-manifest.yaml")) - - By("And the defaultCR file is generated") - Expect(filesIn(workDir)).Should(ContainElement("custom-default-cr.yaml")) - - By("And the security-scanners-config file is generated") - Expect(filesIn(workDir)).Should(ContainElement("custom-security-scanners-config.yaml")) - - By("And the module config file is generated") - Expect(filesIn(workDir)).Should(ContainElement("custom-module-config.yaml")) - - By("And the module config contains expected entries") - actualModConf := moduleConfigFromFile(workDir, "custom-module-config.yaml") - expectedModConf := cmd.toConfigBuilder().get() - Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) - }) - }) - - Context("Given a directory with existing files", func() { - BeforeAll(func() { - setup() - Expect(createMarkerFile("custom-manifest.yaml")).To(Succeed()) - Expect(createMarkerFile("custom-default-cr.yaml")).To(Succeed()) - Expect(createMarkerFile("custom-security-scanners-config.yaml")).To(Succeed()) - }) - AfterAll(func() { teardown() }) - - var cmd createCmd - It("When `modulectl create` command is invoked with arguments that match existing files names", func() { - cmd = createCmd{ - genManifestFlag: "custom-manifest.yaml", - genDefaultCRFlag: "custom-default-cr.yaml", - genSecurityScannersConfigFlag: "custom-security-scanners-config.yaml", - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And there should be four files in the directory") - Expect(filesIn(workDir)).Should(HaveLen(4)) - - By("And the manifest file is reused (not generated)") - Expect(getMarkerFileData("custom-manifest.yaml")).Should(Equal(markerFileData)) - - By("And the defaultCR file is reused (not generated)") - Expect(getMarkerFileData("custom-default-cr.yaml")).Should(Equal(markerFileData)) - - By("And the security-scanners-config file is reused (not generated)") - Expect(getMarkerFileData("custom-security-scanners-config.yaml")).Should(Equal(markerFileData)) - - By("And the module config file is generated") - Expect(filesIn(workDir)).Should(ContainElement("create-module-config.yaml")) - - By("And module config contains expected entries") - actualModConf := moduleConfigFromFile(workDir, "create-module-config.yaml") - expectedModConf := cmd.toConfigBuilder().get() - Expect(actualModConf).To(BeEquivalentTo(expectedModConf)) + By("And module template file should be generated") + Expect(filesIn(workDir)).Should(HaveLen(1)) + Expect(filesIn(workDir)).Should(ContainElement("template.yaml")) }) }) }) - -func getMarkerFileData(name string) string { - data, err := os.ReadFile(name) - Expect(err).ToNot(HaveOccurred()) - return string(data) -} - -func createMarkerFile(name string) error { - err := os.WriteFile(name, []byte(markerFileData), 0o600) - return err -} - -func moduleConfigFromFile(dir, fileName string) *moduleConfig { - filePath := path.Join(dir, fileName) - data, err := os.ReadFile(filePath) - Expect(err).ToNot(HaveOccurred()) - res := moduleConfig{} - err = yaml.Unmarshal(data, &res) - Expect(err).ToNot(HaveOccurred()) - return &res -} - -func filesIn(dir string) []string { - fi, err := os.Stat(dir) - Expect(err).ToNot(HaveOccurred()) - Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) - - dirFs := os.DirFS(dir) - entries, err := fs.ReadDir(dirFs, ".") - Expect(err).ToNot(HaveOccurred()) - - var res []string - for _, ent := range entries { - if ent.Type().IsRegular() { - res = append(res, ent.Name()) - } - } - - return res -} - -func resolveWorkingDirectory() string { - createDir := os.Getenv("CREATE_DIR") - if len(createDir) > 0 { - return createDir - } - - createDir, err := os.MkdirTemp("", "create_test") - if err != nil { - Fail(err.Error()) - } - return createDir -} - -func cleanupWorkingDirectory(path string) { - if len(os.Getenv("CREATE_DIR")) == 0 { - _ = os.RemoveAll(path) - } -} - -type createCmd struct { - moduleName string - moduleVersion string - moduleChannel string - moduleConfigFileFlag string - genDefaultCRFlag string - genSecurityScannersConfigFlag string - genManifestFlag string - overwrite bool -} - -func (cmd *createCmd) execute() error { - var command *exec.Cmd - - // TODO revert to modulectl only debugging against kyma cli bin for verifying tests - args := []string{"alpha", "create", "module"} - - if cmd.moduleName != "" { - args = append(args, "--module-name="+cmd.moduleName) - } - - if cmd.moduleVersion != "" { - args = append(args, "--module-version="+cmd.moduleVersion) - } - - if cmd.moduleChannel != "" { - args = append(args, "--module-channel="+cmd.moduleChannel) - } - - if cmd.moduleConfigFileFlag != "" { - args = append(args, "--module-config="+cmd.moduleConfigFileFlag) - } - - if cmd.genDefaultCRFlag != "" { - args = append(args, "--gen-default-cr="+cmd.genDefaultCRFlag) - } - - if cmd.genSecurityScannersConfigFlag != "" { - args = append(args, "--gen-security-config="+cmd.genSecurityScannersConfigFlag) - } - - if cmd.genManifestFlag != "" { - args = append(args, "--gen-manifest="+cmd.genManifestFlag) - } - - if cmd.overwrite { - args = append(args, "--overwrite=true") - } - - command = exec.Command("kyma", args...) - cmdOut, err := command.CombinedOutput() - if err != nil { - return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) - } - return nil -} - -func (cmd *createCmd) toConfigBuilder() *moduleConfigBuilder { - res := &moduleConfigBuilder{} - res.defaults() - if cmd.moduleName != "" { - res.withName(cmd.moduleName) - } - if cmd.moduleVersion != "" { - res.withVersion(cmd.moduleVersion) - } - if cmd.moduleChannel != "" { - res.withChannel(cmd.moduleChannel) - } - if cmd.genDefaultCRFlag != "" { - res.withDefaultCRPath(cmd.genDefaultCRFlag) - } - if cmd.genSecurityScannersConfigFlag != "" { - res.withSecurityScannersPath(cmd.genSecurityScannersConfigFlag) - } - if cmd.genManifestFlag != "" { - res.withManifestPath(cmd.genManifestFlag) - } - return res -} - -// moduleConfigBuilder is used to simplify module.Config creation for testing purposes -type moduleConfigBuilder struct { - moduleConfig -} - -func (mcb *moduleConfigBuilder) get() *moduleConfig { - res := mcb.moduleConfig - return &res -} - -func (mcb *moduleConfigBuilder) withName(val string) *moduleConfigBuilder { - mcb.Name = val - return mcb -} - -func (mcb *moduleConfigBuilder) withVersion(val string) *moduleConfigBuilder { - mcb.Version = val - return mcb -} - -func (mcb *moduleConfigBuilder) withChannel(val string) *moduleConfigBuilder { - mcb.Channel = val - return mcb -} - -func (mcb *moduleConfigBuilder) withManifestPath(val string) *moduleConfigBuilder { - mcb.ManifestPath = val - return mcb -} - -func (mcb *moduleConfigBuilder) withDefaultCRPath(val string) *moduleConfigBuilder { - mcb.DefaultCRPath = val - return mcb -} - -func (mcb *moduleConfigBuilder) withSecurityScannersPath(val string) *moduleConfigBuilder { - mcb.Security = val - return mcb -} - -func (mcb *moduleConfigBuilder) defaults() *moduleConfigBuilder { - return mcb. - withName("kyma-project.io/module/mymodule"). - withVersion("0.0.1"). - withChannel("regular"). - withManifestPath("manifest.yaml") -} - -// This is a copy of the moduleConfig struct from internal/create/contentprovider/moduleconfig.go -// to not make the moduleConfig public just for the sake of testing. -// It is expected that the moduleConfig struct will be made public in the future when introducing more commands. -// Once it is public, this struct should be removed. -type moduleConfig struct { - Name string `yaml:"name" comment:"required, the name of the Module"` - Version string `yaml:"version" comment:"required, the version of the Module"` - Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"` - ManifestPath string `yaml:"manifest" comment:"required, relative path or remote URL to the manifests"` - Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"` - DefaultCRPath string `yaml:"defaultCR" comment:"optional, relative path or remote URL to a YAML file containing the default CR for the module"` - ResourceName string `yaml:"resourceName" comment:"optional, default={name}-{channel}, when channel is 'none', the default is {name}-{version}, the name for the ModuleTemplate that will be created"` - Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"` - Security string `yaml:"security" comment:"optional, name of the security scanners config file"` - Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"` - Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"` - Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"` - Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"` -} diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index d1b728ac..d8cadc50 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -3,6 +3,10 @@ package create_test import ( + "fmt" + "io/fs" + "os" + "os/exec" "testing" . "github.com/onsi/ginkgo/v2" @@ -13,3 +17,85 @@ func Test_Create(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "'Create' Command Test Suite") } + +// Command wrapper for `modulectl create` + +type createCmd struct { + name string + path string + version string + moduleConfigFile string + moduleArchiveVersionOverwrite bool + insecure bool +} + +func (cmd *createCmd) execute() error { + var command *exec.Cmd + + // TODO revert to modulectl only debugging against kyma cli bin for verifying tests + args := []string{"alpha", "create", "module"} + + if cmd.moduleConfigFile != "" { + args = append(args, "--module-config-file="+cmd.moduleConfigFile) + } + + if cmd.path != "" { + args = append(args, "--path="+cmd.path) + } + + if cmd.name != "" { + args = append(args, "--name="+cmd.name) + } + + if cmd.version != "" { + args = append(args, "--version="+cmd.version) + } + if cmd.moduleArchiveVersionOverwrite { + args = append(args, "--module-archive-version-overwrite") + } + + command = exec.Command("kyma", args...) + cmdOut, err := command.CombinedOutput() + if err != nil { + return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) + } + return nil +} + +func filesIn(dir string) []string { + fi, err := os.Stat(dir) + Expect(err).ToNot(HaveOccurred()) + Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) + + dirFs := os.DirFS(dir) + entries, err := fs.ReadDir(dirFs, ".") + Expect(err).ToNot(HaveOccurred()) + + var res []string + for _, ent := range entries { + if ent.Type().IsRegular() { + res = append(res, ent.Name()) + } + } + + return res +} + +func resolveWorkingDirectory() string { + createDir := os.Getenv("CREATE_DIR") + if len(createDir) > 0 { + return createDir + } + + createDir, err := os.MkdirTemp("", "create_test") + if err != nil { + Fail(err.Error()) + } + return createDir +} + +func cleanupWorkingDirectory(path string) { + if len(os.Getenv("CREATE_DIR")) == 0 { + _ = os.RemoveAll(path) + } +} From 3da148ec0aa0487a2a1e23cfaac15de1fbe9ceb7 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 12 Sep 2024 08:27:39 +0200 Subject: [PATCH 17/40] migrate all e2e tests --- .github/workflows/test-e2e-create.yml | 12 +- tests/e2e/Makefile | 7 +- tests/e2e/create/create_new_test.go | 221 ++++++++++++++++++++++---- tests/e2e/create/create_suite_test.go | 25 +++ tests/e2e/scaffold/scaffold_test.go | 2 +- 5 files changed, 222 insertions(+), 45 deletions(-) diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index 54b08466..b0cff4f9 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -40,9 +40,9 @@ jobs: with: repository: kyma-project/template-operator path: ./template-operator/ - - name: Copy template-operator to e2e folder - run: | - cp -r ./template-operator/* ./tests/e2e/create/ +# - name: Copy template-operator to e2e folder +# run: | +# cp -r ./template-operator/* ./tests/e2e/create/ - name: Set template-operator github URL run: | cd ./template-operator @@ -84,12 +84,6 @@ jobs: - \"**/*_test.go\"" > sec-scanners-config-changed.yaml cat sec-scanners-config-changed.yaml - name: Verify created module template - if: ${{ matrix.e2e-test == 'test-module-create' }} run: | echo $MODULE_TEMPLATE_PATH make -C tests/e2e test-create-cmd - - name: Run E2E tests - if: ${{ matrix.e2e-test == 'test-module-create-same-version'}} - run: | - echo $MODULE_TEMPLATE_PATH - make -C tests/e2e test-create-cmd-same-version diff --git a/tests/e2e/Makefile b/tests/e2e/Makefile index 6ffc2710..2e62884a 100644 --- a/tests/e2e/Makefile +++ b/tests/e2e/Makefile @@ -14,10 +14,7 @@ SHELL = /usr/bin/env bash -o pipefail ##@ E2E Tests test-scaffold-cmd: - go test -tags=e2e ./scaffold -ginkgo.v -ginkgo.focus "Test 'scaffold' Command" + go test -tags=e2e ./scaffold -ginkgo.v -ginkgo.focus "Test 'scaffold' command" test-create-cmd: - go test -tags=e2e ./create -ginkgo.v -ginkgo.focus "Test 'create' Command" - -test-module-create-same-version: - go test -tags=e2e ./create -ginkgo.v -ginkgo.focus "Module Command with same version" + go test -tags=e2e ./create -ginkgo.v -ginkgo.focus "Test 'create' command" diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go index 1b1d9288..0b94cd91 100644 --- a/tests/e2e/create/create_new_test.go +++ b/tests/e2e/create/create_new_test.go @@ -3,47 +3,71 @@ package create_test import ( + "github.com/kyma-project/lifecycle-manager/api/shared" + "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" + "github.com/open-component-model/ocm/pkg/contexts/ocm" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" + ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" + ocmocireg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" "os" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) -var _ = Describe("Test 'create' Command", Ordered, func() { - var initialDir string - var workDir string +var _ = Describe("Test 'create' command", Ordered, func() { + //var initialDir string + //var workDir string + + // TODO remove debugging env + // err := os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") + // err = os.Setenv("TEST_REPOSITORY_URL", "https://github.com/lindnerby/template-operator.git") + // err = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") + // err = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") + + // TODO decide what should be configurable + //ociRepoURL := os.Getenv("OCI_REPOSITORY_URL") + //testRepoURL := os.Getenv("TEST_REPOSITORY_URL") + //templatePath := os.Getenv("MODULE_TEMPLATE_PATH") + //moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") // TODO adapt path for checked out repo on pipeline - moduleRepoPath := "../../../../template-operator" - configFilePath := "../../../../template-operator/module-config.yaml" - //secScannerConfigFile := "../../../../template-operator/sec-scanners-config.yaml" - // + moduleRepoPath := "./testdata/template-operator/" + configFilePath := "./testdata/template-operator/module-config.yaml" + localRegistry := "http://k3d-oci.localhost:5001" + templateOutput := "./testdata/template-operator/template.yaml" + moduleTemplateVersion := "1.0.0" + securityScanConfigFile := "./testdata/template-operator/sec-scanners-config.yaml" + changedSecScanConfigFile := "./testdata/template-operator/sec-scanners-config-changed.yaml" //changedSecScannerConfigFile := "../../../../template-operator/sec-scanners-config-changed.yaml" // TODO see if we can use elegant dir reference to template-operator - setup := func() { - var err error - initialDir, err = os.Getwd() - Expect(err).ToNot(HaveOccurred()) - workDir = resolveWorkingDirectory() - err = os.Chdir(workDir) - Expect(err).ToNot(HaveOccurred()) - } - - teardown := func() { - err := os.Chdir(initialDir) - Expect(err).ToNot(HaveOccurred()) - cleanupWorkingDirectory(workDir) - workDir = "" - initialDir = "" - } + //setup := func() { + // var err error + // initialDir, err = os.Getwd() + // Expect(err).ToNot(HaveOccurred()) + // workDir = resolveWorkingDirectory() + // err = os.Chdir(workDir) + // Expect(err).ToNot(HaveOccurred()) + //} + // + //teardown := func() { + // err := os.Chdir(initialDir) + // Expect(err).ToNot(HaveOccurred()) + // cleanupWorkingDirectory(workDir) + // workDir = "" + // initialDir = "" + //} - Context("Given `modulectl create` command", func() { + Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked without any args", func() { //print current dir currDir, _ := os.Getwd() - By("Current dir: " + currDir) + println(currDir) cmd = createCmd{} }) @@ -53,15 +77,13 @@ var _ = Describe("Test 'create' Command", Ordered, func() { Expect(err).Should(HaveOccurred()) Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) + // TODO //By("And no files are generated") //Expect(filesIn(workDir)).Should(BeEmpty()) }) }) Context("Given `modulectl create` command", func() { - BeforeAll(func() { setup() }) - AfterAll(func() { teardown() }) - var cmd createCmd It("When invoked with --module-config-file and --path", func() { cmd = createCmd{ @@ -72,9 +94,148 @@ var _ = Describe("Test 'create' Command", Ordered, func() { It("Then the command should succeed", func() { Expect(cmd.execute()).To(Succeed()) + By("And no module template file should be generated") + Expect(filesIn("./testdata/template-operator/")).Should(Not(ContainElement("template.yaml"))) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with existing '--registry' and '--insecure' flag", func() { + cmd = createCmd{ + moduleConfigFile: configFilePath, + path: moduleRepoPath, + registry: localRegistry, + insecure: true, + output: templateOutput, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + By("And module template file should be generated") - Expect(filesIn(workDir)).Should(HaveLen(1)) - Expect(filesIn(workDir)).Should(ContainElement("template.yaml")) + Expect(filesIn("./testdata/template-operator/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutput) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + Expect(descriptor.SchemaVersion()).To(Equal(compdescv2.SchemaVersion)) + + By("And annotations should be correct") + annotations := template.Annotations + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal(moduleTemplateVersion)) + Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) + + By("And descriptor.component.repositoryContexts should be correct") + Expect(descriptor.RepositoryContexts).To(HaveLen(1)) + repo := descriptor.GetEffectiveRepositoryContext() + Expect(repo.Object["baseUrl"]).To(Equal(localRegistry)) + Expect(repo.Object["componentNameMapping"]).To(Equal(string(ocmocireg.OCIRegistryURLPathMapping))) + Expect(repo.Object["type"]).To(Equal(ocireg.Type)) + + By("And descriptor.component.resources should be correct") + Expect(descriptor.Resources).To(HaveLen(2)) + resource := descriptor.Resources[0] + Expect(resource.Name).To(Equal("template-operator")) + Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) + Expect(resource.Type).To(Equal("ociImage")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + resource = descriptor.Resources[1] + Expect(resource.Name).To(Equal(rawManifestLayerName)) + Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) + Expect(resource.Type).To(Equal(typeYaml)) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + By("And descriptor.component.resources[0].access should be correct") + resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) + Expect(err).ToNot(HaveOccurred()) + ociArtifactAccessSpec, ok := resourceAccessSpec0.(*ociartifact.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(ociArtifactAccessSpec.GetType()).To(Equal(ociartifact.Type)) + Expect(ociArtifactAccessSpec.ImageReference).To(Equal("europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0")) + + By("And descriptor.component.resources[1].access should be correct") + resourceAccessSpec1, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) + Expect(err).ToNot(HaveOccurred()) + localBlobAccessSpec, ok := resourceAccessSpec1.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + + By("And descriptor.component.sources should be correct") + Expect(len(descriptor.Sources)).To(Equal(1)) + source := descriptor.Sources[0] + sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) + Expect(err).ToNot(HaveOccurred()) + githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(github.Type).To(Equal(githubAccessSpec.Type)) + Expect(githubAccessSpec.RepoURL).To(ContainSubstring("template-operator.git")) + + By("And spec.mandatory should be false") + Expect(template.Spec.Mandatory).To(BeFalse()) + + By("And security scan labels should be correct") + secScanLabels := flatten(descriptor.Sources[0].Labels) + Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "refs/heads/main")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/rc-tag", "1.0.0")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/subprojects", "false")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", "**/test/**,**/*_test.go")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-archive-version-overwrite' flag", func() { + cmd = createCmd{ + path: moduleRepoPath, + registry: localRegistry, + moduleConfigFile: configFilePath, + version: moduleTemplateVersion, + moduleArchiveVersionOverwrite: true, + secScanConfig: securityScanConfigFile, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with same version module and same content without '--module-archive-version-overwrite' flag", func() { + cmd = createCmd{ + path: moduleRepoPath, + registry: localRegistry, + moduleConfigFile: configFilePath, + version: moduleTemplateVersion, + secScanConfig: securityScanConfigFile, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with same version module, but different content without '--module-archive-version-overwrite' flag", func() { + cmd = createCmd{ + path: moduleRepoPath, + registry: localRegistry, + moduleConfigFile: configFilePath, + version: moduleTemplateVersion, + secScanConfig: changedSecScanConfigFile, + } + }) + It("Then the command should fail with same version exists message", func() { + err := cmd.execute() + Expect(err).To(Equal(errCreateModuleFailedWithSameVersion)) }) }) }) diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index d8cadc50..9f1e8233 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -7,6 +7,7 @@ import ( "io/fs" "os" "os/exec" + "strings" "testing" . "github.com/onsi/ginkgo/v2" @@ -22,9 +23,12 @@ func Test_Create(t *testing.T) { type createCmd struct { name string + registry string path string + output string version string moduleConfigFile string + secScanConfig string moduleArchiveVersionOverwrite bool insecure bool } @@ -47,13 +51,34 @@ func (cmd *createCmd) execute() error { args = append(args, "--name="+cmd.name) } + if cmd.registry != "" { + args = append(args, "--registry="+cmd.registry) + } + + if cmd.secScanConfig != "" { + args = append(args, "--sec-scanners-config="+cmd.secScanConfig) + } + + if cmd.output != "" { + args = append(args, "--output="+cmd.output) + } + if cmd.version != "" { args = append(args, "--version="+cmd.version) } + if cmd.moduleArchiveVersionOverwrite { args = append(args, "--module-archive-version-overwrite") } + if cmd.insecure { + args = append(args, "--insecure") + } + + println("Running command: modulectl", strings.Join(args, " ")) + // TODO Remove + args = append(args, "--non-interactive") + command = exec.Command("kyma", args...) cmdOut, err := command.CombinedOutput() if err != nil { diff --git a/tests/e2e/scaffold/scaffold_test.go b/tests/e2e/scaffold/scaffold_test.go index 20714297..1e1a646f 100644 --- a/tests/e2e/scaffold/scaffold_test.go +++ b/tests/e2e/scaffold/scaffold_test.go @@ -19,7 +19,7 @@ const ( markerFileData = "test-marker" ) -var _ = Describe("Test 'scaffold' Command", Ordered, func() { +var _ = Describe("Test 'scaffold' command", Ordered, func() { var initialDir string var workDir string From 10f43cf6c107ed127446c7610ad7b21680d9efcc Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 12 Sep 2024 09:23:27 +0200 Subject: [PATCH 18/40] clean-up --- .github/workflows/test-e2e-create.yml | 27 +--- tests/e2e/create/create_new_test.go | 172 ++++++++++++++-------- tests/e2e/create/create_same_ver_test.go | 2 +- tests/e2e/create/create_suite_test.go | 40 ----- tests/e2e/create/create_test.go | 169 --------------------- tests/e2e/scaffold/scaffold_suite_test.go | 152 +++++++++++++++++++ tests/e2e/scaffold/scaffold_test.go | 152 +------------------ 7 files changed, 268 insertions(+), 446 deletions(-) diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index b0cff4f9..dab17573 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -40,9 +40,10 @@ jobs: with: repository: kyma-project/template-operator path: ./template-operator/ -# - name: Copy template-operator to e2e folder -# run: | -# cp -r ./template-operator/* ./tests/e2e/create/ + - name: Copy template-operator to e2e testdata folder + run: | + mkdir -p ./tests/e2e/create/testdata/template-operator/ + cp -r ./../template-operator/ ./tests/e2e/create/testdata/template-operator/ - name: Set template-operator github URL run: | cd ./template-operator @@ -67,23 +68,7 @@ jobs: --output /tmp/module-config-template.yaml \ --verbose echo "MODULE_TEMPLATE_PATH=/tmp/module-config-template.yaml" >> "$GITHUB_ENV" - - name: Create a different security scanners config file for different layers - if: ${{matrix.e2e-test == 'test-module-create-same-version' }} - run: | - cd ./template-operator - echo \ - "module-name: template-operator - rc-tag: 0.5.0 - dev-branch: main - protecode: - - europe-west3-docker.pkg.dev/sap-kyma-jellyfish-dev/template-operator/component-descriptors/kyma-project.io/template-operator:v1.0.0-e2e-warning - whitesource: - language: golang-mod - exclude: - - \"**/test/**\" - - \"**/*_test.go\"" > sec-scanners-config-changed.yaml - cat sec-scanners-config-changed.yaml - - name: Verify created module template + - name: Run tests run: | - echo $MODULE_TEMPLATE_PATH make -C tests/e2e test-create-cmd + timeout-minutes: 3 diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go index 0b94cd91..67fb2ae4 100644 --- a/tests/e2e/create/create_new_test.go +++ b/tests/e2e/create/create_new_test.go @@ -3,91 +3,66 @@ package create_test import ( - "github.com/kyma-project/lifecycle-manager/api/shared" + "io/fs" + "os" + "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" ocmocireg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" - "os" + "k8s.io/apimachinery/pkg/util/yaml" + + "github.com/kyma-project/lifecycle-manager/api/shared" + "github.com/kyma-project/lifecycle-manager/api/v1beta2" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) var _ = Describe("Test 'create' command", Ordered, func() { - //var initialDir string - //var workDir string - - // TODO remove debugging env - // err := os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") - // err = os.Setenv("TEST_REPOSITORY_URL", "https://github.com/lindnerby/template-operator.git") - // err = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") - // err = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") - - // TODO decide what should be configurable - //ociRepoURL := os.Getenv("OCI_REPOSITORY_URL") - //testRepoURL := os.Getenv("TEST_REPOSITORY_URL") - //templatePath := os.Getenv("MODULE_TEMPLATE_PATH") - //moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") - - // TODO adapt path for checked out repo on pipeline + // _ = os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") + // _ = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") + // _ = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") + + // ociRegistry := os.Getenv("OCI_REPOSITORY_URL") + // testRepoURL := os.Getenv("TEST_REPOSITORY_URL") + // templateOutputPath := os.Getenv("MODULE_TEMPLATE_PATH") + // moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") + + ociRegistry := "http://k3d-oci.localhost:5001" moduleRepoPath := "./testdata/template-operator/" - configFilePath := "./testdata/template-operator/module-config.yaml" - localRegistry := "http://k3d-oci.localhost:5001" - templateOutput := "./testdata/template-operator/template.yaml" moduleTemplateVersion := "1.0.0" - securityScanConfigFile := "./testdata/template-operator/sec-scanners-config.yaml" - changedSecScanConfigFile := "./testdata/template-operator/sec-scanners-config-changed.yaml" - //changedSecScannerConfigFile := "../../../../template-operator/sec-scanners-config-changed.yaml" - - // TODO see if we can use elegant dir reference to template-operator - //setup := func() { - // var err error - // initialDir, err = os.Getwd() - // Expect(err).ToNot(HaveOccurred()) - // workDir = resolveWorkingDirectory() - // err = os.Chdir(workDir) - // Expect(err).ToNot(HaveOccurred()) - //} - // - //teardown := func() { - // err := os.Chdir(initialDir) - // Expect(err).ToNot(HaveOccurred()) - // cleanupWorkingDirectory(workDir) - // workDir = "" - // initialDir = "" - //} + moduleConfigFilePath := moduleRepoPath + "module-config.yaml" + templateOutputPath := moduleRepoPath + "template.yaml" + securityScanConfigFile := moduleRepoPath + "sec-scanners-config.yaml" + changedSecScanConfigFile := moduleRepoPath + "sec-scanners-config-changed.yaml" Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked without any args", func() { - //print current dir - currDir, _ := os.Getwd() - println(currDir) cmd = createCmd{} }) It("Then the command should fail", func() { - cmd = createCmd{} err := cmd.execute() Expect(err).Should(HaveOccurred()) Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - // TODO - //By("And no files are generated") - //Expect(filesIn(workDir)).Should(BeEmpty()) + By("And no module template.yaml is generated") + Expect(filesIn(moduleRepoPath)).Should(Not(ContainElement("template.yaml"))) }) }) - Context("Given `modulectl create` command", func() { + Context("Given 'modulectl create' command", func() { var cmd createCmd - It("When invoked with --module-config-file and --path", func() { + It("When invoked with '--module-config-file' and '--path'", func() { cmd = createCmd{ - moduleConfigFile: configFilePath, + moduleConfigFile: moduleConfigFilePath, path: moduleRepoPath, } }) @@ -103,11 +78,11 @@ var _ = Describe("Test 'create' command", Ordered, func() { var cmd createCmd It("When invoked with existing '--registry' and '--insecure' flag", func() { cmd = createCmd{ - moduleConfigFile: configFilePath, + moduleConfigFile: moduleConfigFilePath, path: moduleRepoPath, - registry: localRegistry, + registry: ociRegistry, insecure: true, - output: templateOutput, + output: templateOutputPath, } }) It("Then the command should succeed", func() { @@ -117,7 +92,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(filesIn("./testdata/template-operator/")).Should(ContainElement("template.yaml")) }) It("Then module template should contain the expected content", func() { - template, err := readModuleTemplate(templateOutput) + template, err := readModuleTemplate(templateOutputPath) Expect(err).ToNot(HaveOccurred()) descriptor := getDescriptor(template) Expect(descriptor).ToNot(BeNil()) @@ -131,7 +106,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { By("And descriptor.component.repositoryContexts should be correct") Expect(descriptor.RepositoryContexts).To(HaveLen(1)) repo := descriptor.GetEffectiveRepositoryContext() - Expect(repo.Object["baseUrl"]).To(Equal(localRegistry)) + Expect(repo.Object["baseUrl"]).To(Equal(ociRegistry)) Expect(repo.Object["componentNameMapping"]).To(Equal(string(ocmocireg.OCIRegistryURLPathMapping))) Expect(repo.Object["type"]).To(Equal(ocireg.Type)) @@ -144,9 +119,9 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(resource.Version).To(Equal(moduleTemplateVersion)) resource = descriptor.Resources[1] - Expect(resource.Name).To(Equal(rawManifestLayerName)) + Expect(resource.Name).To(Equal("raw-manifest")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) - Expect(resource.Type).To(Equal(typeYaml)) + Expect(resource.Type).To(Equal("yaml")) Expect(resource.Version).To(Equal(moduleTemplateVersion)) By("And descriptor.component.resources[0].access should be correct") @@ -194,8 +169,8 @@ var _ = Describe("Test 'create' command", Ordered, func() { It("When invoked with '--module-archive-version-overwrite' flag", func() { cmd = createCmd{ path: moduleRepoPath, - registry: localRegistry, - moduleConfigFile: configFilePath, + registry: ociRegistry, + moduleConfigFile: moduleConfigFilePath, version: moduleTemplateVersion, moduleArchiveVersionOverwrite: true, secScanConfig: securityScanConfigFile, @@ -211,8 +186,8 @@ var _ = Describe("Test 'create' command", Ordered, func() { It("When invoked with same version module and same content without '--module-archive-version-overwrite' flag", func() { cmd = createCmd{ path: moduleRepoPath, - registry: localRegistry, - moduleConfigFile: configFilePath, + registry: ociRegistry, + moduleConfigFile: moduleConfigFilePath, version: moduleTemplateVersion, secScanConfig: securityScanConfigFile, } @@ -227,8 +202,8 @@ var _ = Describe("Test 'create' command", Ordered, func() { It("When invoked with same version module, but different content without '--module-archive-version-overwrite' flag", func() { cmd = createCmd{ path: moduleRepoPath, - registry: localRegistry, - moduleConfigFile: configFilePath, + registry: ociRegistry, + moduleConfigFile: moduleConfigFilePath, version: moduleTemplateVersion, secScanConfig: changedSecScanConfigFile, } @@ -239,3 +214,70 @@ var _ = Describe("Test 'create' command", Ordered, func() { }) }) }) + +// Test helper functions + +func readModuleTemplate(filepath string) (*v1beta2.ModuleTemplate, error) { + moduleTemplate := &v1beta2.ModuleTemplate{} + moduleFile, err := os.ReadFile(filepath) + if err != nil && len(moduleFile) > 0 { + return nil, err + } + err = yaml.Unmarshal(moduleFile, moduleTemplate) + if err != nil { + return nil, err + } + return moduleTemplate, err +} + +func getDescriptor(template *v1beta2.ModuleTemplate) *v1beta2.Descriptor { + if template.Spec.Descriptor.Object != nil { + desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) + if !ok || desc == nil { + return nil + } + return desc + } + ocmDesc, err := compdesc.Decode( + template.Spec.Descriptor.Raw, + []compdesc.DecodeOption{compdesc.DisableValidation(true)}...) + if err != nil { + return nil + } + template.Spec.Descriptor.Object = &v1beta2.Descriptor{ComponentDescriptor: ocmDesc} + desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) + if !ok { + return nil + } + + return desc +} + +func flatten(labels ocmmetav1.Labels) map[string]string { + labelsMap := make(map[string]string) + for _, l := range labels { + var value string + _ = yaml.Unmarshal(l.Value, &value) + labelsMap[l.Name] = value + } + return labelsMap +} + +func filesIn(dir string) []string { + fi, err := os.Stat(dir) + Expect(err).ToNot(HaveOccurred()) + Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) + + dirFs := os.DirFS(dir) + entries, err := fs.ReadDir(dirFs, ".") + Expect(err).ToNot(HaveOccurred()) + + var res []string + for _, ent := range entries { + if ent.Type().IsRegular() { + res = append(res, ent.Name()) + } + } + + return res +} diff --git a/tests/e2e/create/create_same_ver_test.go b/tests/e2e/create/create_same_ver_test.go index 500dafed..113bf620 100644 --- a/tests/e2e/create/create_same_ver_test.go +++ b/tests/e2e/create/create_same_ver_test.go @@ -14,7 +14,7 @@ import ( ) var errCreateModuleFailedWithSameVersion = errors.New( - "failed to create module with same version exists message") + "version 1.0.0 already exists with different content, please use --module-archive-version-overwrite flag to overwrite it") const ( ociRepositoryEnvVar = "OCI_REPOSITORY_URL" diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index 9f1e8233..f6b64089 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -4,8 +4,6 @@ package create_test import ( "fmt" - "io/fs" - "os" "os/exec" "strings" "testing" @@ -86,41 +84,3 @@ func (cmd *createCmd) execute() error { } return nil } - -func filesIn(dir string) []string { - fi, err := os.Stat(dir) - Expect(err).ToNot(HaveOccurred()) - Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) - - dirFs := os.DirFS(dir) - entries, err := fs.ReadDir(dirFs, ".") - Expect(err).ToNot(HaveOccurred()) - - var res []string - for _, ent := range entries { - if ent.Type().IsRegular() { - res = append(res, ent.Name()) - } - } - - return res -} - -func resolveWorkingDirectory() string { - createDir := os.Getenv("CREATE_DIR") - if len(createDir) > 0 { - return createDir - } - - createDir, err := os.MkdirTemp("", "create_test") - if err != nil { - Fail(err.Error()) - } - return createDir -} - -func cleanupWorkingDirectory(path string) { - if len(os.Getenv("CREATE_DIR")) == 0 { - _ = os.RemoveAll(path) - } -} diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index a0394edc..83f4d402 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -1,172 +1,3 @@ //go:build e2e package create_test - -import ( - "os" - "testing" - - "github.com/kyma-project/lifecycle-manager/api/shared" - "github.com/kyma-project/lifecycle-manager/api/v1beta2" - "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" - "github.com/open-component-model/ocm/pkg/contexts/ocm" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" - "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" - ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" - compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" - ocmocireg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/util/yaml" -) - -const ( - rawManifestLayerName = "raw-manifest" - typeYaml = "yaml" -) - -func Test_ModuleTemplate(t *testing.T) { - // TODO remove debugging env - // err := os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") - // err = os.Setenv("TEST_REPOSITORY_URL", "https://github.com/lindnerby/template-operator.git") - // err = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") - // err = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") - - ociRepoURL := os.Getenv("OCI_REPOSITORY_URL") - testRepoURL := os.Getenv("TEST_REPOSITORY_URL") - templatePath := os.Getenv("MODULE_TEMPLATE_PATH") - - template, err := readModuleTemplate(templatePath) - require.NoError(t, err) - descriptor := getDescriptor(template) - assert.NotNil(t, descriptor) - assert.Equal(t, compdescv2.SchemaVersion, descriptor.SchemaVersion()) - - t.Run("test annotations", func(t *testing.T) { - annotations := template.Annotations - expectedModuleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") - assert.Equal(t, expectedModuleTemplateVersion, annotations[shared.ModuleVersionAnnotation]) - assert.Equal(t, "false", annotations[shared.IsClusterScopedAnnotation]) - }) - - t.Run("test descriptor.component.repositoryContexts", func(t *testing.T) { - assert.Len(t, 1, len(descriptor.RepositoryContexts)) - repo := descriptor.GetEffectiveRepositoryContext() - assert.Equal(t, ociRepoURL, repo.Object["baseUrl"]) - assert.Equal(t, string(ocmocireg.OCIRegistryURLPathMapping), repo.Object["componentNameMapping"]) - assert.Equal(t, ocireg.Type, repo.Object["type"]) - }) - - t.Run("test descriptor.component.resources", func(t *testing.T) { - assert.Len(t, 2, len(descriptor.Resources)) - - resource := descriptor.Resources[0] - assert.Equal(t, "template-operator", resource.Name) - assert.Equal(t, ocmmetav1.ExternalRelation, resource.Relation) - assert.Equal(t, "ociImage", resource.Type) - expectedModuleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") - assert.Equal(t, expectedModuleTemplateVersion, resource.Version) - - resource = descriptor.Resources[1] - assert.Equal(t, rawManifestLayerName, resource.Name) - assert.Equal(t, ocmmetav1.LocalRelation, resource.Relation) - assert.Equal(t, typeYaml, resource.Type) - assert.Equal(t, expectedModuleTemplateVersion, resource.Version) - }) - - t.Run("test descriptor.component.resources[0].access", func(t *testing.T) { - resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) - require.NoError(t, err) - ociArtifactAccessSpec, ok := resourceAccessSpec.(*ociartifact.AccessSpec) - assert.True(t, ok) - assert.Equal(t, ociartifact.Type, ociArtifactAccessSpec.GetType()) - assert.Equal(t, "europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0", - ociArtifactAccessSpec.ImageReference) - }) - - t.Run("test descriptor.component.resources[1].access", func(t *testing.T) { - resourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) - require.NoError(t, err) - localBlobAccessSpec, ok := resourceAccessSpec.(*localblob.AccessSpec) - assert.True(t, ok) - assert.Equal(t, localblob.Type, localBlobAccessSpec.GetType()) - assert.Contains(t, localBlobAccessSpec.LocalReference, "sha256:") - }) - - t.Run("test descriptor.component.sources", func(t *testing.T) { - assert.Len(t, len(descriptor.Sources), 1) - source := descriptor.Sources[0] - sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) - require.NoError(t, err) - githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) - assert.True(t, ok) - assert.Equal(t, github.Type, githubAccessSpec.Type) - assert.Contains(t, testRepoURL, githubAccessSpec.RepoURL) - }) - - t.Run("test spec.mandatory", func(t *testing.T) { - assert.False(t, template.Spec.Mandatory) - }) - - t.Run("test security scan labels", func(t *testing.T) { - secScanLabels := descriptor.Sources[0].Labels - flattenedLabels := flatten(secScanLabels) - assert.Equal(t, map[string]string{ - "git.kyma-project.io/ref": "refs/heads/main", - "scan.security.kyma-project.io/rc-tag": "1.0.0", - "scan.security.kyma-project.io/language": "golang-mod", - "scan.security.kyma-project.io/dev-branch": "main", - "scan.security.kyma-project.io/subprojects": "false", - "scan.security.kyma-project.io/exclude": "**/test/**,**/*_test.go", - }, flattenedLabels) - }) -} - -func readModuleTemplate(filepath string) (*v1beta2.ModuleTemplate, error) { - moduleTemplate := &v1beta2.ModuleTemplate{} - moduleFile, err := os.ReadFile(filepath) - if err != nil && len(moduleFile) > 0 { - return nil, err - } - err = yaml.Unmarshal(moduleFile, moduleTemplate) - if err != nil { - return nil, err - } - return moduleTemplate, err -} - -func getDescriptor(template *v1beta2.ModuleTemplate) *v1beta2.Descriptor { - if template.Spec.Descriptor.Object != nil { - desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) - if !ok || desc == nil { - return nil - } - return desc - } - ocmDesc, err := compdesc.Decode( - template.Spec.Descriptor.Raw, - []compdesc.DecodeOption{compdesc.DisableValidation(true)}...) - if err != nil { - return nil - } - template.Spec.Descriptor.Object = &v1beta2.Descriptor{ComponentDescriptor: ocmDesc} - desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) - if !ok { - return nil - } - - return desc -} - -func flatten(labels ocmmetav1.Labels) map[string]string { - labelsMap := make(map[string]string) - for _, l := range labels { - var value string - _ = yaml.Unmarshal(l.Value, &value) - labelsMap[l.Name] = value - } - - return labelsMap -} diff --git a/tests/e2e/scaffold/scaffold_suite_test.go b/tests/e2e/scaffold/scaffold_suite_test.go index cf65da6c..a666607d 100644 --- a/tests/e2e/scaffold/scaffold_suite_test.go +++ b/tests/e2e/scaffold/scaffold_suite_test.go @@ -3,6 +3,8 @@ package scaffold_test import ( + "fmt" + "os/exec" "testing" . "github.com/onsi/ginkgo/v2" @@ -13,3 +15,153 @@ func Test_Scaffold(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "'Scaffold' Command Test Suite") } + +// Command wrapper for `modulectl scaffold` + +type scaffoldCmd struct { + moduleName string + moduleVersion string + moduleChannel string + moduleConfigFileFlag string + genDefaultCRFlag string + genSecurityScannersConfigFlag string + genManifestFlag string + overwrite bool +} + +func (cmd *scaffoldCmd) execute() error { + var command *exec.Cmd + + args := []string{"scaffold"} + + if cmd.moduleName != "" { + args = append(args, "--module-name="+cmd.moduleName) + } + + if cmd.moduleVersion != "" { + args = append(args, "--module-version="+cmd.moduleVersion) + } + + if cmd.moduleChannel != "" { + args = append(args, "--module-channel="+cmd.moduleChannel) + } + + if cmd.moduleConfigFileFlag != "" { + args = append(args, "--module-config="+cmd.moduleConfigFileFlag) + } + + if cmd.genDefaultCRFlag != "" { + args = append(args, "--gen-default-cr="+cmd.genDefaultCRFlag) + } + + if cmd.genSecurityScannersConfigFlag != "" { + args = append(args, "--gen-security-config="+cmd.genSecurityScannersConfigFlag) + } + + if cmd.genManifestFlag != "" { + args = append(args, "--gen-manifest="+cmd.genManifestFlag) + } + + if cmd.overwrite { + args = append(args, "--overwrite=true") + } + + command = exec.Command("modulectl", args...) + cmdOut, err := command.CombinedOutput() + if err != nil { + return fmt.Errorf("scaffold command failed with output: %s and error: %w", cmdOut, err) + } + return nil +} + +func (cmd *scaffoldCmd) toConfigBuilder() *moduleConfigBuilder { + res := &moduleConfigBuilder{} + res.defaults() + if cmd.moduleName != "" { + res.withName(cmd.moduleName) + } + if cmd.moduleVersion != "" { + res.withVersion(cmd.moduleVersion) + } + if cmd.moduleChannel != "" { + res.withChannel(cmd.moduleChannel) + } + if cmd.genDefaultCRFlag != "" { + res.withDefaultCRPath(cmd.genDefaultCRFlag) + } + if cmd.genSecurityScannersConfigFlag != "" { + res.withSecurityScannersPath(cmd.genSecurityScannersConfigFlag) + } + if cmd.genManifestFlag != "" { + res.withManifestPath(cmd.genManifestFlag) + } + return res +} + +// moduleConfigBuilder is used to simplify module.Config creation for testing purposes +type moduleConfigBuilder struct { + moduleConfig +} + +func (mcb *moduleConfigBuilder) get() *moduleConfig { + res := mcb.moduleConfig + return &res +} + +func (mcb *moduleConfigBuilder) withName(val string) *moduleConfigBuilder { + mcb.Name = val + return mcb +} + +func (mcb *moduleConfigBuilder) withVersion(val string) *moduleConfigBuilder { + mcb.Version = val + return mcb +} + +func (mcb *moduleConfigBuilder) withChannel(val string) *moduleConfigBuilder { + mcb.Channel = val + return mcb +} + +func (mcb *moduleConfigBuilder) withManifestPath(val string) *moduleConfigBuilder { + mcb.ManifestPath = val + return mcb +} + +func (mcb *moduleConfigBuilder) withDefaultCRPath(val string) *moduleConfigBuilder { + mcb.DefaultCRPath = val + return mcb +} + +func (mcb *moduleConfigBuilder) withSecurityScannersPath(val string) *moduleConfigBuilder { + mcb.Security = val + return mcb +} + +func (mcb *moduleConfigBuilder) defaults() *moduleConfigBuilder { + return mcb. + withName("kyma-project.io/module/mymodule"). + withVersion("0.0.1"). + withChannel("regular"). + withManifestPath("manifest.yaml") +} + +// This is a copy of the moduleConfig struct from internal/scaffold/contentprovider/moduleconfig.go +// to not make the moduleConfig public just for the sake of testing. +// It is expected that the moduleConfig struct will be made public in the future when introducing more commands. +// Once it is public, this struct should be removed. +type moduleConfig struct { + Name string `yaml:"name" comment:"required, the name of the Module"` + Version string `yaml:"version" comment:"required, the version of the Module"` + Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"` + ManifestPath string `yaml:"manifest" comment:"required, relative path or remote URL to the manifests"` + Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"` + DefaultCRPath string `yaml:"defaultCR" comment:"optional, relative path or remote URL to a YAML file containing the default CR for the module"` + ResourceName string `yaml:"resourceName" comment:"optional, default={name}-{channel}, when channel is 'none', the default is {name}-{version}, the name for the ModuleTemplate that will be created"` + Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"` + Security string `yaml:"security" comment:"optional, name of the security scanners config file"` + Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"` + Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"` + Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"` + Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"` +} diff --git a/tests/e2e/scaffold/scaffold_test.go b/tests/e2e/scaffold/scaffold_test.go index 1e1a646f..d20e17e6 100644 --- a/tests/e2e/scaffold/scaffold_test.go +++ b/tests/e2e/scaffold/scaffold_test.go @@ -3,10 +3,8 @@ package scaffold_test import ( - "fmt" "io/fs" "os" - "os/exec" "path" "gopkg.in/yaml.v3" @@ -208,6 +206,8 @@ var _ = Describe("Test 'scaffold' command", Ordered, func() { }) }) +// Test helper functions + func getMarkerFileData(name string) string { data, err := os.ReadFile(name) Expect(err).ToNot(HaveOccurred()) @@ -266,151 +266,3 @@ func cleanupWorkingDirectory(path string) { _ = os.RemoveAll(path) } } - -type scaffoldCmd struct { - moduleName string - moduleVersion string - moduleChannel string - moduleConfigFileFlag string - genDefaultCRFlag string - genSecurityScannersConfigFlag string - genManifestFlag string - overwrite bool -} - -func (cmd *scaffoldCmd) execute() error { - var command *exec.Cmd - - args := []string{"scaffold"} - - if cmd.moduleName != "" { - args = append(args, "--module-name="+cmd.moduleName) - } - - if cmd.moduleVersion != "" { - args = append(args, "--module-version="+cmd.moduleVersion) - } - - if cmd.moduleChannel != "" { - args = append(args, "--module-channel="+cmd.moduleChannel) - } - - if cmd.moduleConfigFileFlag != "" { - args = append(args, "--module-config="+cmd.moduleConfigFileFlag) - } - - if cmd.genDefaultCRFlag != "" { - args = append(args, "--gen-default-cr="+cmd.genDefaultCRFlag) - } - - if cmd.genSecurityScannersConfigFlag != "" { - args = append(args, "--gen-security-config="+cmd.genSecurityScannersConfigFlag) - } - - if cmd.genManifestFlag != "" { - args = append(args, "--gen-manifest="+cmd.genManifestFlag) - } - - if cmd.overwrite { - args = append(args, "--overwrite=true") - } - - command = exec.Command("modulectl", args...) - cmdOut, err := command.CombinedOutput() - if err != nil { - return fmt.Errorf("scaffold command failed with output: %s and error: %w", cmdOut, err) - } - return nil -} - -func (cmd *scaffoldCmd) toConfigBuilder() *moduleConfigBuilder { - res := &moduleConfigBuilder{} - res.defaults() - if cmd.moduleName != "" { - res.withName(cmd.moduleName) - } - if cmd.moduleVersion != "" { - res.withVersion(cmd.moduleVersion) - } - if cmd.moduleChannel != "" { - res.withChannel(cmd.moduleChannel) - } - if cmd.genDefaultCRFlag != "" { - res.withDefaultCRPath(cmd.genDefaultCRFlag) - } - if cmd.genSecurityScannersConfigFlag != "" { - res.withSecurityScannersPath(cmd.genSecurityScannersConfigFlag) - } - if cmd.genManifestFlag != "" { - res.withManifestPath(cmd.genManifestFlag) - } - return res -} - -// moduleConfigBuilder is used to simplify module.Config creation for testing purposes -type moduleConfigBuilder struct { - moduleConfig -} - -func (mcb *moduleConfigBuilder) get() *moduleConfig { - res := mcb.moduleConfig - return &res -} - -func (mcb *moduleConfigBuilder) withName(val string) *moduleConfigBuilder { - mcb.Name = val - return mcb -} - -func (mcb *moduleConfigBuilder) withVersion(val string) *moduleConfigBuilder { - mcb.Version = val - return mcb -} - -func (mcb *moduleConfigBuilder) withChannel(val string) *moduleConfigBuilder { - mcb.Channel = val - return mcb -} - -func (mcb *moduleConfigBuilder) withManifestPath(val string) *moduleConfigBuilder { - mcb.ManifestPath = val - return mcb -} - -func (mcb *moduleConfigBuilder) withDefaultCRPath(val string) *moduleConfigBuilder { - mcb.DefaultCRPath = val - return mcb -} - -func (mcb *moduleConfigBuilder) withSecurityScannersPath(val string) *moduleConfigBuilder { - mcb.Security = val - return mcb -} - -func (mcb *moduleConfigBuilder) defaults() *moduleConfigBuilder { - return mcb. - withName("kyma-project.io/module/mymodule"). - withVersion("0.0.1"). - withChannel("regular"). - withManifestPath("manifest.yaml") -} - -// This is a copy of the moduleConfig struct from internal/scaffold/contentprovider/moduleconfig.go -// to not make the moduleConfig public just for the sake of testing. -// It is expected that the moduleConfig struct will be made public in the future when introducing more commands. -// Once it is public, this struct should be removed. -type moduleConfig struct { - Name string `yaml:"name" comment:"required, the name of the Module"` - Version string `yaml:"version" comment:"required, the version of the Module"` - Channel string `yaml:"channel" comment:"required, channel that should be used in the ModuleTemplate"` - ManifestPath string `yaml:"manifest" comment:"required, relative path or remote URL to the manifests"` - Mandatory bool `yaml:"mandatory" comment:"optional, default=false, indicates whether the module is mandatory to be installed on all clusters"` - DefaultCRPath string `yaml:"defaultCR" comment:"optional, relative path or remote URL to a YAML file containing the default CR for the module"` - ResourceName string `yaml:"resourceName" comment:"optional, default={name}-{channel}, when channel is 'none', the default is {name}-{version}, the name for the ModuleTemplate that will be created"` - Namespace string `yaml:"namespace" comment:"optional, default=kcp-system, the namespace where the ModuleTemplate will be deployed"` - Security string `yaml:"security" comment:"optional, name of the security scanners config file"` - Internal bool `yaml:"internal" comment:"optional, default=false, determines whether the ModuleTemplate should have the internal flag or not"` - Beta bool `yaml:"beta" comment:"optional, default=false, determines whether the ModuleTemplate should have the beta flag or not"` - Labels map[string]string `yaml:"labels" comment:"optional, additional labels for the ModuleTemplate"` - Annotations map[string]string `yaml:"annotations" comment:"optional, additional annotations for the ModuleTemplate"` -} From cafe3f8ba058dd1dbbb3434329692a99ae933d4c Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 12 Sep 2024 09:32:40 +0200 Subject: [PATCH 19/40] clean-up --- .github/workflows/test-e2e-create.yml | 23 +- tests/e2e/create/create_new_test.go | 283 ---------------------- tests/e2e/create/create_same_ver_test.go | 72 ------ tests/e2e/create/create_suite_test.go | 12 +- tests/e2e/create/create_test.go | 284 +++++++++++++++++++++++ 5 files changed, 293 insertions(+), 381 deletions(-) delete mode 100644 tests/e2e/create/create_new_test.go delete mode 100644 tests/e2e/create/create_same_ver_test.go diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index dab17573..31e0f1be 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -10,11 +10,6 @@ on: - 'release-**' jobs: test-create-cmd: - strategy: - matrix: - e2e-test: [ 'test-module-create', - 'test-module-create-same-version' ] - name: E2E test - module create runs-on: ubuntu-latest env: K3D_VERSION: v5.4.7 @@ -48,26 +43,14 @@ jobs: run: | cd ./template-operator echo "TEST_REPOSITORY_URL=$(git remote get-url origin)" >> "$GITHUB_ENV" - - name: Install k3d - run: wget -qO - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=$K3D_VERSION bash - - name: Provision OCI Registry + - name: Install k3d and create registry run: | + wget -qO - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=$K3D_VERSION bash k3d registry create oci.localhost --port 5001 - - name: Run create module with module-config + - name: Make manifests template-operator run: | cd ./template-operator make build-manifests - modulectl create \ - --name kyma-project.io/module/template-operator \ - --path . \ - --registry http://k3d-oci.localhost:5001 \ - --insecure \ - --module-config-file ./module-config.yaml \ - --version $MODULE_TEMPLATE_VERSION \ - --sec-scanners-config sec-scanners-config.yaml \ - --output /tmp/module-config-template.yaml \ - --verbose - echo "MODULE_TEMPLATE_PATH=/tmp/module-config-template.yaml" >> "$GITHUB_ENV" - name: Run tests run: | make -C tests/e2e test-create-cmd diff --git a/tests/e2e/create/create_new_test.go b/tests/e2e/create/create_new_test.go deleted file mode 100644 index 67fb2ae4..00000000 --- a/tests/e2e/create/create_new_test.go +++ /dev/null @@ -1,283 +0,0 @@ -//go:build e2e - -package create_test - -import ( - "io/fs" - "os" - - "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" - "github.com/open-component-model/ocm/pkg/contexts/ocm" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" - "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" - ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" - compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" - ocmocireg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" - "k8s.io/apimachinery/pkg/util/yaml" - - "github.com/kyma-project/lifecycle-manager/api/shared" - "github.com/kyma-project/lifecycle-manager/api/v1beta2" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("Test 'create' command", Ordered, func() { - // _ = os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") - // _ = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") - // _ = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") - - // ociRegistry := os.Getenv("OCI_REPOSITORY_URL") - // testRepoURL := os.Getenv("TEST_REPOSITORY_URL") - // templateOutputPath := os.Getenv("MODULE_TEMPLATE_PATH") - // moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") - - ociRegistry := "http://k3d-oci.localhost:5001" - moduleRepoPath := "./testdata/template-operator/" - moduleTemplateVersion := "1.0.0" - moduleConfigFilePath := moduleRepoPath + "module-config.yaml" - templateOutputPath := moduleRepoPath + "template.yaml" - securityScanConfigFile := moduleRepoPath + "sec-scanners-config.yaml" - changedSecScanConfigFile := moduleRepoPath + "sec-scanners-config-changed.yaml" - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked without any args", func() { - cmd = createCmd{} - }) - - It("Then the command should fail", func() { - err := cmd.execute() - Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - - By("And no module template.yaml is generated") - Expect(filesIn(moduleRepoPath)).Should(Not(ContainElement("template.yaml"))) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with '--module-config-file' and '--path'", func() { - cmd = createCmd{ - moduleConfigFile: moduleConfigFilePath, - path: moduleRepoPath, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And no module template file should be generated") - Expect(filesIn("./testdata/template-operator/")).Should(Not(ContainElement("template.yaml"))) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with existing '--registry' and '--insecure' flag", func() { - cmd = createCmd{ - moduleConfigFile: moduleConfigFilePath, - path: moduleRepoPath, - registry: ociRegistry, - insecure: true, - output: templateOutputPath, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And module template file should be generated") - Expect(filesIn("./testdata/template-operator/")).Should(ContainElement("template.yaml")) - }) - It("Then module template should contain the expected content", func() { - template, err := readModuleTemplate(templateOutputPath) - Expect(err).ToNot(HaveOccurred()) - descriptor := getDescriptor(template) - Expect(descriptor).ToNot(BeNil()) - Expect(descriptor.SchemaVersion()).To(Equal(compdescv2.SchemaVersion)) - - By("And annotations should be correct") - annotations := template.Annotations - Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal(moduleTemplateVersion)) - Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) - - By("And descriptor.component.repositoryContexts should be correct") - Expect(descriptor.RepositoryContexts).To(HaveLen(1)) - repo := descriptor.GetEffectiveRepositoryContext() - Expect(repo.Object["baseUrl"]).To(Equal(ociRegistry)) - Expect(repo.Object["componentNameMapping"]).To(Equal(string(ocmocireg.OCIRegistryURLPathMapping))) - Expect(repo.Object["type"]).To(Equal(ocireg.Type)) - - By("And descriptor.component.resources should be correct") - Expect(descriptor.Resources).To(HaveLen(2)) - resource := descriptor.Resources[0] - Expect(resource.Name).To(Equal("template-operator")) - Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) - Expect(resource.Type).To(Equal("ociImage")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) - - resource = descriptor.Resources[1] - Expect(resource.Name).To(Equal("raw-manifest")) - Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) - Expect(resource.Type).To(Equal("yaml")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) - - By("And descriptor.component.resources[0].access should be correct") - resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) - Expect(err).ToNot(HaveOccurred()) - ociArtifactAccessSpec, ok := resourceAccessSpec0.(*ociartifact.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(ociArtifactAccessSpec.GetType()).To(Equal(ociartifact.Type)) - Expect(ociArtifactAccessSpec.ImageReference).To(Equal("europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0")) - - By("And descriptor.component.resources[1].access should be correct") - resourceAccessSpec1, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) - Expect(err).ToNot(HaveOccurred()) - localBlobAccessSpec, ok := resourceAccessSpec1.(*localblob.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) - Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) - - By("And descriptor.component.sources should be correct") - Expect(len(descriptor.Sources)).To(Equal(1)) - source := descriptor.Sources[0] - sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) - Expect(err).ToNot(HaveOccurred()) - githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(github.Type).To(Equal(githubAccessSpec.Type)) - Expect(githubAccessSpec.RepoURL).To(ContainSubstring("template-operator.git")) - - By("And spec.mandatory should be false") - Expect(template.Spec.Mandatory).To(BeFalse()) - - By("And security scan labels should be correct") - secScanLabels := flatten(descriptor.Sources[0].Labels) - Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "refs/heads/main")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/rc-tag", "1.0.0")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/subprojects", "false")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", "**/test/**,**/*_test.go")) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with '--module-archive-version-overwrite' flag", func() { - cmd = createCmd{ - path: moduleRepoPath, - registry: ociRegistry, - moduleConfigFile: moduleConfigFilePath, - version: moduleTemplateVersion, - moduleArchiveVersionOverwrite: true, - secScanConfig: securityScanConfigFile, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with same version module and same content without '--module-archive-version-overwrite' flag", func() { - cmd = createCmd{ - path: moduleRepoPath, - registry: ociRegistry, - moduleConfigFile: moduleConfigFilePath, - version: moduleTemplateVersion, - secScanConfig: securityScanConfigFile, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with same version module, but different content without '--module-archive-version-overwrite' flag", func() { - cmd = createCmd{ - path: moduleRepoPath, - registry: ociRegistry, - moduleConfigFile: moduleConfigFilePath, - version: moduleTemplateVersion, - secScanConfig: changedSecScanConfigFile, - } - }) - It("Then the command should fail with same version exists message", func() { - err := cmd.execute() - Expect(err).To(Equal(errCreateModuleFailedWithSameVersion)) - }) - }) -}) - -// Test helper functions - -func readModuleTemplate(filepath string) (*v1beta2.ModuleTemplate, error) { - moduleTemplate := &v1beta2.ModuleTemplate{} - moduleFile, err := os.ReadFile(filepath) - if err != nil && len(moduleFile) > 0 { - return nil, err - } - err = yaml.Unmarshal(moduleFile, moduleTemplate) - if err != nil { - return nil, err - } - return moduleTemplate, err -} - -func getDescriptor(template *v1beta2.ModuleTemplate) *v1beta2.Descriptor { - if template.Spec.Descriptor.Object != nil { - desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) - if !ok || desc == nil { - return nil - } - return desc - } - ocmDesc, err := compdesc.Decode( - template.Spec.Descriptor.Raw, - []compdesc.DecodeOption{compdesc.DisableValidation(true)}...) - if err != nil { - return nil - } - template.Spec.Descriptor.Object = &v1beta2.Descriptor{ComponentDescriptor: ocmDesc} - desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) - if !ok { - return nil - } - - return desc -} - -func flatten(labels ocmmetav1.Labels) map[string]string { - labelsMap := make(map[string]string) - for _, l := range labels { - var value string - _ = yaml.Unmarshal(l.Value, &value) - labelsMap[l.Name] = value - } - return labelsMap -} - -func filesIn(dir string) []string { - fi, err := os.Stat(dir) - Expect(err).ToNot(HaveOccurred()) - Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) - - dirFs := os.DirFS(dir) - entries, err := fs.ReadDir(dirFs, ".") - Expect(err).ToNot(HaveOccurred()) - - var res []string - for _, ent := range entries { - if ent.Type().IsRegular() { - res = append(res, ent.Name()) - } - } - - return res -} diff --git a/tests/e2e/create/create_same_ver_test.go b/tests/e2e/create/create_same_ver_test.go deleted file mode 100644 index 113bf620..00000000 --- a/tests/e2e/create/create_same_ver_test.go +++ /dev/null @@ -1,72 +0,0 @@ -//go:build e2e - -package create_test - -import ( - "errors" - "fmt" - "os" - "os/exec" - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -var errCreateModuleFailedWithSameVersion = errors.New( - "version 1.0.0 already exists with different content, please use --module-archive-version-overwrite flag to overwrite it") - -const ( - ociRepositoryEnvVar = "OCI_REPOSITORY_URL" - moduleTemplateVersionEnvVar = "MODULE_TEMPLATE_VERSION" -) - -func Test_SameVersion_ModuleCreation(t *testing.T) { - path := "../../../template-operator" - configFilePath := "../../../template-operator/module-config.yaml" - secScannerConfigFile := "../../../template-operator/sec-scanners-config.yaml" - changedSecScannerConfigFile := "../../../template-operator/sec-scanners-config-changed.yaml" - version := os.Getenv(moduleTemplateVersionEnvVar) - registry := os.Getenv(ociRepositoryEnvVar) - - t.Run("Create same version module with module-archive-version-overwrite flag", func(t *testing.T) { - err := createModuleCommand(true, path, registry, configFilePath, version, secScannerConfigFile) - assert.NoError(t, err) - }) - - t.Run("Create same version module and same content without module-archive-version-overwrite flag", - func(t *testing.T) { - err := createModuleCommand(false, path, registry, configFilePath, version, secScannerConfigFile) - assert.NoError(t, err) - }) - - t.Run("Create same version module, but different content without module-archive-version-overwrite flag", - func(t *testing.T) { - err := createModuleCommand(false, path, registry, configFilePath, version, changedSecScannerConfigFile) - assert.Equal(t, errCreateModuleFailedWithSameVersion, err) - }) -} - -func createModuleCommand(versionOverwrite bool, - path, registry, configFilePath, version, secScannerConfig string, -) error { - var createModuleCmd *exec.Cmd - if versionOverwrite { - createModuleCmd = exec.Command("kyma", "alpha", "create", "module", - "--path", path, "--registry", registry, "--insecure", "--module-config-file", configFilePath, - "--version", version, "--module-archive-version-overwrite", "--sec-scanners-config", secScannerConfig) - } else { - createModuleCmd = exec.Command("kyma", "alpha", "create", "module", - "--path", path, "--registry", registry, "--insecure", "--module-config-file", configFilePath, - "--version", version, "--sec-scanners-config", secScannerConfig) - } - createOut, err := createModuleCmd.CombinedOutput() - if err != nil { - if strings.Contains(string(createOut), - fmt.Sprintf("version %s already exists with different content", version)) { - return errCreateModuleFailedWithSameVersion - } - return fmt.Errorf("create module command failed: %w", err) - } - return nil -} diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index f6b64089..6c1d9218 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -34,8 +34,8 @@ type createCmd struct { func (cmd *createCmd) execute() error { var command *exec.Cmd - // TODO revert to modulectl only debugging against kyma cli bin for verifying tests - args := []string{"alpha", "create", "module"} + //args := []string{"alpha", "create", "module"} + args := []string{"create"} if cmd.moduleConfigFile != "" { args = append(args, "--module-config-file="+cmd.moduleConfigFile) @@ -73,11 +73,11 @@ func (cmd *createCmd) execute() error { args = append(args, "--insecure") } - println("Running command: modulectl", strings.Join(args, " ")) - // TODO Remove - args = append(args, "--non-interactive") + println(" >>> Executing command: modulectl", strings.Join(args, " ")) + //args = append(args, "--non-interactive") + //command = exec.Command("kyma", args...) - command = exec.Command("kyma", args...) + command = exec.Command("modulectl", args...) cmdOut, err := command.CombinedOutput() if err != nil { return fmt.Errorf("create command failed with output: %s and error: %w", cmdOut, err) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 83f4d402..5211b929 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -1,3 +1,287 @@ //go:build e2e package create_test + +import ( + "errors" + "io/fs" + "os" + + "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" + "github.com/open-component-model/ocm/pkg/contexts/ocm" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" + ocmocireg "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg" + "k8s.io/apimachinery/pkg/util/yaml" + + "github.com/kyma-project/lifecycle-manager/api/shared" + "github.com/kyma-project/lifecycle-manager/api/v1beta2" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var errCreateModuleFailedWithSameVersion = errors.New( + "version 1.0.0 already exists with different content, please use --module-archive-version-overwrite flag to overwrite it") + +var _ = Describe("Test 'create' command", Ordered, func() { + // _ = os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") + // _ = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") + // _ = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") + + // ociRegistry := os.Getenv("OCI_REPOSITORY_URL") + // testRepoURL := os.Getenv("TEST_REPOSITORY_URL") + // templateOutputPath := os.Getenv("MODULE_TEMPLATE_PATH") + // moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") + + ociRegistry := "http://k3d-oci.localhost:5001" + moduleRepoPath := "./testdata/template-operator/" + moduleTemplateVersion := "1.0.0" + moduleConfigFilePath := moduleRepoPath + "module-config.yaml" + templateOutputPath := moduleRepoPath + "template.yaml" + securityScanConfigFile := moduleRepoPath + "sec-scanners-config.yaml" + changedSecScanConfigFile := moduleRepoPath + "sec-scanners-config-changed.yaml" + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked without any args", func() { + cmd = createCmd{} + }) + + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) + + By("And no module template.yaml is generated") + Expect(filesIn(moduleRepoPath)).Should(Not(ContainElement("template.yaml"))) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-config-file' and '--path'", func() { + cmd = createCmd{ + moduleConfigFile: moduleConfigFilePath, + path: moduleRepoPath, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And no module template file should be generated") + Expect(filesIn("./testdata/template-operator/")).Should(Not(ContainElement("template.yaml"))) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with existing '--registry' and '--insecure' flag", func() { + cmd = createCmd{ + moduleConfigFile: moduleConfigFilePath, + path: moduleRepoPath, + registry: ociRegistry, + insecure: true, + output: templateOutputPath, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And module template file should be generated") + Expect(filesIn("./testdata/template-operator/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutputPath) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + Expect(descriptor.SchemaVersion()).To(Equal(compdescv2.SchemaVersion)) + + By("And annotations should be correct") + annotations := template.Annotations + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal(moduleTemplateVersion)) + Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) + + By("And descriptor.component.repositoryContexts should be correct") + Expect(descriptor.RepositoryContexts).To(HaveLen(1)) + repo := descriptor.GetEffectiveRepositoryContext() + Expect(repo.Object["baseUrl"]).To(Equal(ociRegistry)) + Expect(repo.Object["componentNameMapping"]).To(Equal(string(ocmocireg.OCIRegistryURLPathMapping))) + Expect(repo.Object["type"]).To(Equal(ocireg.Type)) + + By("And descriptor.component.resources should be correct") + Expect(descriptor.Resources).To(HaveLen(2)) + resource := descriptor.Resources[0] + Expect(resource.Name).To(Equal("template-operator")) + Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) + Expect(resource.Type).To(Equal("ociImage")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + resource = descriptor.Resources[1] + Expect(resource.Name).To(Equal("raw-manifest")) + Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) + Expect(resource.Type).To(Equal("yaml")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + By("And descriptor.component.resources[0].access should be correct") + resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) + Expect(err).ToNot(HaveOccurred()) + ociArtifactAccessSpec, ok := resourceAccessSpec0.(*ociartifact.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(ociArtifactAccessSpec.GetType()).To(Equal(ociartifact.Type)) + Expect(ociArtifactAccessSpec.ImageReference).To(Equal("europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0")) + + By("And descriptor.component.resources[1].access should be correct") + resourceAccessSpec1, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) + Expect(err).ToNot(HaveOccurred()) + localBlobAccessSpec, ok := resourceAccessSpec1.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + + By("And descriptor.component.sources should be correct") + Expect(len(descriptor.Sources)).To(Equal(1)) + source := descriptor.Sources[0] + sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) + Expect(err).ToNot(HaveOccurred()) + githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(github.Type).To(Equal(githubAccessSpec.Type)) + Expect(githubAccessSpec.RepoURL).To(ContainSubstring("template-operator.git")) + + By("And spec.mandatory should be false") + Expect(template.Spec.Mandatory).To(BeFalse()) + + By("And security scan labels should be correct") + secScanLabels := flatten(descriptor.Sources[0].Labels) + Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "refs/heads/main")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/rc-tag", "1.0.0")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/subprojects", "false")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", "**/test/**,**/*_test.go")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-archive-version-overwrite' flag", func() { + cmd = createCmd{ + path: moduleRepoPath, + registry: ociRegistry, + moduleConfigFile: moduleConfigFilePath, + version: moduleTemplateVersion, + moduleArchiveVersionOverwrite: true, + secScanConfig: securityScanConfigFile, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with same version module and same content without '--module-archive-version-overwrite' flag", func() { + cmd = createCmd{ + path: moduleRepoPath, + registry: ociRegistry, + moduleConfigFile: moduleConfigFilePath, + version: moduleTemplateVersion, + secScanConfig: securityScanConfigFile, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with same version module, but different content without '--module-archive-version-overwrite' flag", func() { + cmd = createCmd{ + path: moduleRepoPath, + registry: ociRegistry, + moduleConfigFile: moduleConfigFilePath, + version: moduleTemplateVersion, + secScanConfig: changedSecScanConfigFile, + } + }) + It("Then the command should fail with same version exists message", func() { + err := cmd.execute() + Expect(err).To(Equal(errCreateModuleFailedWithSameVersion)) + }) + }) +}) + +// Test helper functions + +func readModuleTemplate(filepath string) (*v1beta2.ModuleTemplate, error) { + moduleTemplate := &v1beta2.ModuleTemplate{} + moduleFile, err := os.ReadFile(filepath) + if err != nil && len(moduleFile) > 0 { + return nil, err + } + err = yaml.Unmarshal(moduleFile, moduleTemplate) + if err != nil { + return nil, err + } + return moduleTemplate, err +} + +func getDescriptor(template *v1beta2.ModuleTemplate) *v1beta2.Descriptor { + if template.Spec.Descriptor.Object != nil { + desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) + if !ok || desc == nil { + return nil + } + return desc + } + ocmDesc, err := compdesc.Decode( + template.Spec.Descriptor.Raw, + []compdesc.DecodeOption{compdesc.DisableValidation(true)}...) + if err != nil { + return nil + } + template.Spec.Descriptor.Object = &v1beta2.Descriptor{ComponentDescriptor: ocmDesc} + desc, ok := template.Spec.Descriptor.Object.(*v1beta2.Descriptor) + if !ok { + return nil + } + + return desc +} + +func flatten(labels ocmmetav1.Labels) map[string]string { + labelsMap := make(map[string]string) + for _, l := range labels { + var value string + _ = yaml.Unmarshal(l.Value, &value) + labelsMap[l.Name] = value + } + return labelsMap +} + +func filesIn(dir string) []string { + fi, err := os.Stat(dir) + Expect(err).ToNot(HaveOccurred()) + Expect(fi.IsDir()).To(BeTrueBecause("The provided path should be a directory: %s", dir)) + + dirFs := os.DirFS(dir) + entries, err := fs.ReadDir(dirFs, ".") + Expect(err).ToNot(HaveOccurred()) + + var res []string + for _, ent := range entries { + if ent.Type().IsRegular() { + res = append(res, ent.Name()) + } + } + + return res +} From aaf87755b4ea76357be33972fde51488e2a203f2 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Fri, 13 Sep 2024 15:10:05 +0200 Subject: [PATCH 20/40] adapt some review issues --- cmd/modulectl/create/cmd.go | 2 +- cmd/modulectl/create/cmd_test.go | 2 +- cmd/modulectl/scaffold/cmd.go | 2 +- cmd/modulectl/scaffold/cmd_test.go | 2 +- internal/service/scaffold/options_test.go | 123 ++++++++++--- internal/service/scaffold/scaffold_test.go | 201 --------------------- tests/e2e/create/create_suite_test.go | 3 - tests/e2e/create/create_test.go | 4 +- 8 files changed, 99 insertions(+), 240 deletions(-) diff --git a/cmd/modulectl/create/cmd.go b/cmd/modulectl/create/cmd.go index f0dc3969..549b166a 100644 --- a/cmd/modulectl/create/cmd.go +++ b/cmd/modulectl/create/cmd.go @@ -30,7 +30,7 @@ type Service interface { func NewCmd(service Service) (*cobra.Command, error) { if service == nil { - return nil, fmt.Errorf("%w: create Service must not be nil", commonerrors.ErrInvalidArg) + return nil, fmt.Errorf("%w: service must not be nil", commonerrors.ErrInvalidArg) } opts := create.Options{} diff --git a/cmd/modulectl/create/cmd_test.go b/cmd/modulectl/create/cmd_test.go index 2ab44fde..3a383fb2 100644 --- a/cmd/modulectl/create/cmd_test.go +++ b/cmd/modulectl/create/cmd_test.go @@ -18,7 +18,7 @@ func Test_NewCmd_ReturnsError_WhenModuleServiceIsNil(t *testing.T) { _, err := createcmd.NewCmd(nil) require.Error(t, err) - assert.Contains(t, err.Error(), "create Service") + assert.Contains(t, err.Error(), "service must not be nil") } func Test_NewCmd_Succeeds(t *testing.T) { diff --git a/cmd/modulectl/scaffold/cmd.go b/cmd/modulectl/scaffold/cmd.go index 2089407e..2ec3c380 100644 --- a/cmd/modulectl/scaffold/cmd.go +++ b/cmd/modulectl/scaffold/cmd.go @@ -30,7 +30,7 @@ type Service interface { func NewCmd(service Service) (*cobra.Command, error) { if service == nil { - return nil, fmt.Errorf("%w: scaffold Service must not be nil", commonerrors.ErrInvalidArg) + return nil, fmt.Errorf("%w: service must not be nil", commonerrors.ErrInvalidArg) } opts := scaffold.Options{} diff --git a/cmd/modulectl/scaffold/cmd_test.go b/cmd/modulectl/scaffold/cmd_test.go index e72939d6..a97d78d8 100644 --- a/cmd/modulectl/scaffold/cmd_test.go +++ b/cmd/modulectl/scaffold/cmd_test.go @@ -17,7 +17,7 @@ func Test_NewCmd_ReturnsError_WhenScaffoldServiceIsNil(t *testing.T) { _, err := scaffoldcmd.NewCmd(nil) require.Error(t, err) - assert.Contains(t, err.Error(), "scaffold Service") + assert.Contains(t, err.Error(), "service must not be nil") } func Test_NewCmd_Succceeds(t *testing.T) { diff --git a/internal/service/scaffold/options_test.go b/internal/service/scaffold/options_test.go index 89c6080a..de0d4e5c 100644 --- a/internal/service/scaffold/options_test.go +++ b/internal/service/scaffold/options_test.go @@ -25,79 +25,127 @@ func Test_Validate_Options(t *testing.T) { errMsg: "opts.Out must not be nil", }, { - name: "ModuleName is empty", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: ""}, + name: "ModuleName is empty", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "", + }, wantErr: true, errMsg: "opts.ModuleName must not be empty", }, { - name: "ModuleName exceeds length", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: strings.Repeat("a", 256)}, + name: "ModuleName exceeds length", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: strings.Repeat("a", 256), + }, wantErr: true, errMsg: "opts.ModuleName length must not exceed", }, { - name: "ModuleName invalid pattern", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "invalid_name"}, + name: "ModuleName invalid pattern", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "invalid_name", + }, wantErr: true, errMsg: "opts.ModuleName must match the required pattern", }, { - name: "Directory is empty", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: ""}, + name: "Directory is empty", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "", + }, wantErr: true, errMsg: "opts.Directory must not be empty", }, { - name: "ModuleVersion is empty", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: ""}, + name: "ModuleVersion is empty", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "", + }, wantErr: true, errMsg: "opts.ModuleVersion must not be empty", }, { - name: "ModuleVersion invalid", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "invalid"}, + name: "ModuleVersion invalid", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "invalid", + }, wantErr: true, errMsg: "opts.ModuleVersion failed to parse as semantic version", }, { - name: "ModuleChannel is empty", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: ""}, + name: "ModuleChannel is empty", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: "", + }, wantErr: true, errMsg: "opts.ModuleChannel must not be empty", }, { - name: "ModuleChannel exceeds length", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: strings.Repeat("a", 33)}, + name: "ModuleChannel exceeds length", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: strings.Repeat("a", 33), + }, wantErr: true, errMsg: "opts.ModuleChannel length must not exceed", }, { - name: "ModuleChannel below minimum length", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "aa"}, + name: "ModuleChannel below minimum length", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: "aa", + }, wantErr: true, errMsg: "opts.ModuleChannel length must be at least", }, { - name: "ModuleChannel invalid pattern", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "invalid_channel"}, + name: "ModuleChannel invalid pattern", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: "invalid_channel", + }, wantErr: true, errMsg: "opts.ModuleChannel must match the required pattern", }, { - name: "ModuleConfigFileName is empty", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "stable", ModuleConfigFileName: ""}, + name: "ModuleConfigFileName is empty", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: "stable", + ModuleConfigFileName: "", + }, wantErr: true, errMsg: "opts.ModuleConfigFileName must not be empty", }, { - name: "ManifestFileName is empty", - options: scaffold.Options{Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", Directory: "./", ModuleVersion: "0.0.1", ModuleChannel: "stable", ModuleConfigFileName: "config.yaml", ManifestFileName: ""}, - wantErr: true, - errMsg: "opts.ManifestFileName must not be empty", - }, - { - name: "All fields valid", + name: "ManifestFileName is empty", options: scaffold.Options{ Out: iotools.NewDefaultOut(io.Discard), ModuleName: "github.com/kyma-project/test", @@ -105,7 +153,22 @@ func Test_Validate_Options(t *testing.T) { ModuleVersion: "0.0.1", ModuleChannel: "stable", ModuleConfigFileName: "config.yaml", - ManifestFileName: "manifest.yaml", + ManifestFileName: "", + }, + wantErr: true, + errMsg: "opts.ManifestFileName must not be empty", + }, + { + name: "All fields valid", + options: scaffold.Options{ + Out: iotools.NewDefaultOut(io.Discard), + ModuleName: "github.com/kyma-project/test", + Directory: "./", + ModuleVersion: "0.0.1", + ModuleChannel: "stable", + ModuleConfigFileName: "config.yaml", + ManifestFileName: "manifest.yaml", + SecurityConfigFileName: "", }, wantErr: false, }, diff --git a/internal/service/scaffold/scaffold_test.go b/internal/service/scaffold/scaffold_test.go index f73e942d..8355b2f3 100644 --- a/internal/service/scaffold/scaffold_test.go +++ b/internal/service/scaffold/scaffold_test.go @@ -11,7 +11,6 @@ import ( commonerrors "github.com/kyma-project/modulectl/internal/common/errors" "github.com/kyma-project/modulectl/internal/common/types" "github.com/kyma-project/modulectl/internal/service/scaffold" - "github.com/kyma-project/modulectl/internal/testutils" iotools "github.com/kyma-project/modulectl/tools/io" ) @@ -59,194 +58,6 @@ func Test_NewService_ReturnsError_WhenSecurityConfigServiceIsNil(t *testing.T) { assert.Contains(t, err.Error(), "securityConfigService") } -func Test_CreateScaffold_ReturnsError_WhenOutIsNil(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withOut(nil).build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.Out") -} - -func Test_CreateScaffold_ReturnsError_WhenDirectoryIsEmpty(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withDirectory("").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.Directory") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleConfigFileName("").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleConfigFileName") -} - -func Test_CreateScaffold_ReturnsError_WhenManifestFileIsEmpty(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withManifestFileName("").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ManifestFileName") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleNameIsEmpty(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleName("").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleName") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleNameIsExceedingLength(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleName(testutils.RandomName(256)).build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleName") - assert.Contains(t, result.Error(), "length") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleNameIsNotMatchingPattern(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleName(testutils.RandomName(10)).build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleName") - assert.Contains(t, result.Error(), "pattern") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleVersionIsEmpty(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleVersion("").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleVersion") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleVersionIsInvalid(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleVersion(testutils.RandomName(10)).build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleVersion") - assert.Contains(t, result.Error(), "failed to parse") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleChannelIsEmpty(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleChannel("").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleChannel") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleChannelIsExceedingLength(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleChannel(testutils.RandomName(33)).build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleChannel") - assert.Contains(t, result.Error(), "length") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleChannelFallsBelowLength(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleChannel(testutils.RandomName(2)).build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleChannel") - assert.Contains(t, result.Error(), "length") -} - -func Test_CreateScaffold_ReturnsError_WhenModuleChannelNotMatchingCharset(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigForceExplicitOverwriteErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}, - &fileGeneratorErrorStub{}) - opts := newScaffoldOptionsBuilder().withModuleChannel("with not allowed chars 123%&").build() - - result := svc.Run(opts) - - require.ErrorIs(t, result, commonerrors.ErrInvalidOption) - assert.Contains(t, result.Error(), "opts.ModuleChannel") - assert.Contains(t, result.Error(), "pattern") -} - func Test_CreateScaffold_ReturnsError_WhenModuleConfigServiceForceExplicitOverwriteReturnsError(t *testing.T) { svc, _ := scaffold.NewService( &moduleConfigForceExplicitOverwriteErrorStub{}, @@ -323,18 +134,6 @@ func Test_CreateScaffold_Succeeds_WhenGeneratingDefaultCRFile(t *testing.T) { require.NoError(t, result) } -func Test_CreateScaffold_Succeeds_WhenSecurityConfigFileIsNotConfigured(t *testing.T) { - svc, _ := scaffold.NewService( - &moduleConfigStub{}, - &fileGeneratorStub{}, - &fileGeneratorStub{}, - &fileGeneratorErrorStub{}) - - result := svc.Run(newScaffoldOptionsBuilder().withSecurityConfigFileName("").build()) - - require.NoError(t, result) -} - func Test_CreateScaffold_ReturnsError_WhenGeneratingSecurityConfigFileFails(t *testing.T) { svc, _ := scaffold.NewService( &moduleConfigGenerateFileErrorStub{}, diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index 6c1d9218..646f925a 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -34,7 +34,6 @@ type createCmd struct { func (cmd *createCmd) execute() error { var command *exec.Cmd - //args := []string{"alpha", "create", "module"} args := []string{"create"} if cmd.moduleConfigFile != "" { @@ -74,8 +73,6 @@ func (cmd *createCmd) execute() error { } println(" >>> Executing command: modulectl", strings.Join(args, " ")) - //args = append(args, "--non-interactive") - //command = exec.Command("kyma", args...) command = exec.Command("modulectl", args...) cmdOut, err := command.CombinedOutput() diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 5211b929..e81d5406 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -196,7 +196,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { secScanConfig: securityScanConfigFile, } }) - It("Then the command should succeed", func() { + It("Then the command should succeed, because content has not change and overwrite flag not needed", func() { Expect(cmd.execute()).To(Succeed()) }) }) @@ -212,7 +212,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { secScanConfig: changedSecScanConfigFile, } }) - It("Then the command should fail with same version exists message", func() { + It("Then the command should fail with same version exists message, because overwrite flag is required", func() { err := cmd.execute() Expect(err).To(Equal(errCreateModuleFailedWithSameVersion)) }) From f26ab1ee6f8065547c6b26a4519a4baf7d290082 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Tue, 24 Sep 2024 12:00:46 +0200 Subject: [PATCH 21/40] Add registryUrl != "" check --- internal/service/create/options.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/create/options.go b/internal/service/create/options.go index e39ba56d..9f9939b5 100644 --- a/internal/service/create/options.go +++ b/internal/service/create/options.go @@ -45,7 +45,7 @@ func (opts Options) Validate() error { return fmt.Errorf("%w: opts.TemplateOutput must not be empty", commonerrors.ErrInvalidOption) } - if !strings.HasPrefix(opts.RegistryURL, "http") { + if opts.RegistryURL != "" && !strings.HasPrefix(opts.RegistryURL, "http") { return fmt.Errorf("%w: opts.RegistryURL does not start with http(s)", commonerrors.ErrInvalidOption) } From 34f5f0814ac3a105a4cd683b9de171f1d3dc9ae7 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 12:20:28 +0200 Subject: [PATCH 22/40] adapt testcases to new modulectl api --- .github/workflows/test-e2e-create.yml | 21 +-- tests/e2e/create/create_suite_test.go | 34 +---- tests/e2e/create/create_test.go | 126 ++++++++++-------- .../module-config-missing-required.yaml | 7 + .../create/testdata/module-config-valid.yaml | 8 ++ 5 files changed, 94 insertions(+), 102 deletions(-) create mode 100644 tests/e2e/create/testdata/module-config-missing-required.yaml create mode 100644 tests/e2e/create/testdata/module-config-valid.yaml diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index 31e0f1be..11d46443 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -30,27 +30,14 @@ jobs: ls -la ./bin mv ./bin/modulectl-linux /usr/local/bin/modulectl timeout-minutes: 5 - - name: Checkout template-operator - uses: actions/checkout@v4 - with: - repository: kyma-project/template-operator - path: ./template-operator/ - - name: Copy template-operator to e2e testdata folder - run: | - mkdir -p ./tests/e2e/create/testdata/template-operator/ - cp -r ./../template-operator/ ./tests/e2e/create/testdata/template-operator/ - - name: Set template-operator github URL - run: | - cd ./template-operator - echo "TEST_REPOSITORY_URL=$(git remote get-url origin)" >> "$GITHUB_ENV" +# - name: Set template-operator github URL +# run: | +# cd ./template-operator +# echo "TEST_REPOSITORY_URL=$(git remote get-url origin)" >> "$GITHUB_ENV" - name: Install k3d and create registry run: | wget -qO - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=$K3D_VERSION bash k3d registry create oci.localhost --port 5001 - - name: Make manifests template-operator - run: | - cd ./template-operator - make build-manifests - name: Run tests run: | make -C tests/e2e test-create-cmd diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index 646f925a..8a7f3077 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -20,15 +20,11 @@ func Test_Create(t *testing.T) { // Command wrapper for `modulectl create` type createCmd struct { - name string - registry string - path string - output string - version string - moduleConfigFile string - secScanConfig string - moduleArchiveVersionOverwrite bool - insecure bool + registry string + output string + moduleConfigFile string + gitRemote string + insecure bool } func (cmd *createCmd) execute() error { @@ -40,32 +36,16 @@ func (cmd *createCmd) execute() error { args = append(args, "--module-config-file="+cmd.moduleConfigFile) } - if cmd.path != "" { - args = append(args, "--path="+cmd.path) - } - - if cmd.name != "" { - args = append(args, "--name="+cmd.name) - } - if cmd.registry != "" { args = append(args, "--registry="+cmd.registry) } - if cmd.secScanConfig != "" { - args = append(args, "--sec-scanners-config="+cmd.secScanConfig) - } - if cmd.output != "" { args = append(args, "--output="+cmd.output) } - if cmd.version != "" { - args = append(args, "--version="+cmd.version) - } - - if cmd.moduleArchiveVersionOverwrite { - args = append(args, "--module-archive-version-overwrite") + if cmd.gitRemote != "" { + args = append(args, "--git-remote="+cmd.gitRemote) } if cmd.insecure { diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index e81d5406..c046269b 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -39,12 +39,17 @@ var _ = Describe("Test 'create' command", Ordered, func() { // moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") ociRegistry := "http://k3d-oci.localhost:5001" - moduleRepoPath := "./testdata/template-operator/" moduleTemplateVersion := "1.0.0" - moduleConfigFilePath := moduleRepoPath + "module-config.yaml" - templateOutputPath := moduleRepoPath + "template.yaml" - securityScanConfigFile := moduleRepoPath + "sec-scanners-config.yaml" - changedSecScanConfigFile := moduleRepoPath + "sec-scanners-config-changed.yaml" + + // TODO build module-config file in test + validModuleConfigFile := "./testdata/module-config-valid.yaml" + invalidModuleConfigFile := "./testdata/module-config-missing-required.yaml" + + templateOutputPath := "/tmp/template.yaml" + + // TODO build module-config file in test + //securityScanConfigFile := moduleRepoPath + "sec-scanners-config.yaml" + //changedSecScanConfigFile := moduleRepoPath + "sec-scanners-config-changed.yaml" Context("Given 'modulectl create' command", func() { var cmd createCmd @@ -56,18 +61,14 @@ var _ = Describe("Test 'create' command", Ordered, func() { err := cmd.execute() Expect(err).Should(HaveOccurred()) Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - - By("And no module template.yaml is generated") - Expect(filesIn(moduleRepoPath)).Should(Not(ContainElement("template.yaml"))) }) }) Context("Given 'modulectl create' command", func() { var cmd createCmd - It("When invoked with '--module-config-file' and '--path'", func() { + It("When invoked with '--module-config-file' using valid file", func() { cmd = createCmd{ - moduleConfigFile: moduleConfigFilePath, - path: moduleRepoPath, + moduleConfigFile: validModuleConfigFile, } }) It("Then the command should succeed", func() { @@ -78,12 +79,40 @@ var _ = Describe("Test 'create' command", Ordered, func() { }) }) + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-config-file' using file with missing required fields", func() { + cmd = createCmd{ + moduleConfigFile: invalidModuleConfigFile, + } + }) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("Error: field is required")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with existing '--registry' and missing '--insecure' flag", func() { + cmd = createCmd{ + moduleConfigFile: validModuleConfigFile, + registry: ociRegistry, + } + }) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("Error: could not push")) + }) + }) + Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked with existing '--registry' and '--insecure' flag", func() { cmd = createCmd{ - moduleConfigFile: moduleConfigFilePath, - path: moduleRepoPath, + moduleConfigFile: validModuleConfigFile, registry: ociRegistry, insecure: true, output: templateOutputPath, @@ -93,7 +122,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(cmd.execute()).To(Succeed()) By("And module template file should be generated") - Expect(filesIn("./testdata/template-operator/")).Should(ContainElement("template.yaml")) + Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) }) It("Then module template should contain the expected content", func() { template, err := readModuleTemplate(templateOutputPath) @@ -119,13 +148,19 @@ var _ = Describe("Test 'create' command", Ordered, func() { resource := descriptor.Resources[0] Expect(resource.Name).To(Equal("template-operator")) Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) - Expect(resource.Type).To(Equal("ociImage")) + Expect(resource.Type).To(Equal("ociArtifact")) Expect(resource.Version).To(Equal(moduleTemplateVersion)) resource = descriptor.Resources[1] Expect(resource.Name).To(Equal("raw-manifest")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) - Expect(resource.Type).To(Equal("yaml")) + Expect(resource.Type).To(Equal("directory")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + resource = descriptor.Resources[2] + Expect(resource.Name).To(Equal("default-cr")) + Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) + Expect(resource.Type).To(Equal("directory")) Expect(resource.Version).To(Equal(moduleTemplateVersion)) By("And descriptor.component.resources[0].access should be correct") @@ -143,6 +178,16 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(ok).To(BeTrue()) Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + Expect(localBlobAccessSpec.MediaType).To(Equal("application/x-tar")) + + By("And descriptor.component.resources[2].access should be correct") + defaultCRResourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[2].Access) + Expect(err).ToNot(HaveOccurred()) + defaultCRAccessSpec, ok := defaultCRResourceAccessSpec.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(defaultCRAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(defaultCRAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + Expect(defaultCRAccessSpec.MediaType).To(Equal("application/x-tar")) By("And descriptor.component.sources should be correct") Expect(len(descriptor.Sources)).To(Equal(1)) @@ -152,14 +197,14 @@ var _ = Describe("Test 'create' command", Ordered, func() { githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) Expect(ok).To(BeTrue()) Expect(github.Type).To(Equal(githubAccessSpec.Type)) - Expect(githubAccessSpec.RepoURL).To(ContainSubstring("template-operator.git")) + Expect(githubAccessSpec.RepoURL).To(Equal("https://github.com/kyma-project/template-operator")) By("And spec.mandatory should be false") Expect(template.Spec.Mandatory).To(BeFalse()) By("And security scan labels should be correct") secScanLabels := flatten(descriptor.Sources[0].Labels) - Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "refs/heads/main")) + Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "HEAD")) Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/rc-tag", "1.0.0")) Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) @@ -170,51 +215,16 @@ var _ = Describe("Test 'create' command", Ordered, func() { Context("Given 'modulectl create' command", func() { var cmd createCmd - It("When invoked with '--module-archive-version-overwrite' flag", func() { + It("When invoked with same version that already exists in the registry", func() { cmd = createCmd{ - path: moduleRepoPath, - registry: ociRegistry, - moduleConfigFile: moduleConfigFilePath, - version: moduleTemplateVersion, - moduleArchiveVersionOverwrite: true, - secScanConfig: securityScanConfigFile, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with same version module and same content without '--module-archive-version-overwrite' flag", func() { - cmd = createCmd{ - path: moduleRepoPath, + moduleConfigFile: validModuleConfigFile, registry: ociRegistry, - moduleConfigFile: moduleConfigFilePath, - version: moduleTemplateVersion, - secScanConfig: securityScanConfigFile, - } - }) - It("Then the command should succeed, because content has not change and overwrite flag not needed", func() { - Expect(cmd.execute()).To(Succeed()) - }) - }) - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with same version module, but different content without '--module-archive-version-overwrite' flag", func() { - cmd = createCmd{ - path: moduleRepoPath, - registry: ociRegistry, - moduleConfigFile: moduleConfigFilePath, - version: moduleTemplateVersion, - secScanConfig: changedSecScanConfigFile, + insecure: true, } }) - It("Then the command should fail with same version exists message, because overwrite flag is required", func() { + It("Then the command should fail with same version exists message", func() { err := cmd.execute() - Expect(err).To(Equal(errCreateModuleFailedWithSameVersion)) + Expect(err.Error()).Should(ContainSubstring("could not push component version: component version already exists")) }) }) }) diff --git a/tests/e2e/create/testdata/module-config-missing-required.yaml b/tests/e2e/create/testdata/module-config-missing-required.yaml new file mode 100644 index 00000000..9e48649c --- /dev/null +++ b/tests/e2e/create/testdata/module-config-missing-required.yaml @@ -0,0 +1,7 @@ +channel: regular +version: 1.0.0 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml +security: sec-scanners-config.yaml +defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml +annotations: + operator.kyma-project.io/doc-url: https://kyma-project.io diff --git a/tests/e2e/create/testdata/module-config-valid.yaml b/tests/e2e/create/testdata/module-config-valid.yaml new file mode 100644 index 00000000..c36fc1bf --- /dev/null +++ b/tests/e2e/create/testdata/module-config-valid.yaml @@ -0,0 +1,8 @@ +name: kyma-project.io/module/template-operator +channel: regular +version: 1.0.0 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml +security: sec-scanners-config.yaml +defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml +annotations: + operator.kyma-project.io/doc-url: https://kyma-project.io From abd17c238bcbe5ed40642385538cd3af42584b8f Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 12:21:45 +0200 Subject: [PATCH 23/40] clean-up --- tests/e2e/create/create_test.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index c046269b..792bed69 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -3,7 +3,6 @@ package create_test import ( - "errors" "io/fs" "os" @@ -25,9 +24,6 @@ import ( . "github.com/onsi/gomega" ) -var errCreateModuleFailedWithSameVersion = errors.New( - "version 1.0.0 already exists with different content, please use --module-archive-version-overwrite flag to overwrite it") - var _ = Describe("Test 'create' command", Ordered, func() { // _ = os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") // _ = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") @@ -41,16 +37,12 @@ var _ = Describe("Test 'create' command", Ordered, func() { ociRegistry := "http://k3d-oci.localhost:5001" moduleTemplateVersion := "1.0.0" - // TODO build module-config file in test + // TODO build module-config file in tests? validModuleConfigFile := "./testdata/module-config-valid.yaml" invalidModuleConfigFile := "./testdata/module-config-missing-required.yaml" templateOutputPath := "/tmp/template.yaml" - // TODO build module-config file in test - //securityScanConfigFile := moduleRepoPath + "sec-scanners-config.yaml" - //changedSecScanConfigFile := moduleRepoPath + "sec-scanners-config-changed.yaml" - Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked without any args", func() { From 08d649194befe46fffd34f5b891c71d15ec5a831 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Tue, 24 Sep 2024 12:38:34 +0200 Subject: [PATCH 24/40] Revert "Add registryUrl != "" check" This reverts commit f26ab1ee6f8065547c6b26a4519a4baf7d290082. --- internal/service/create/options.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/create/options.go b/internal/service/create/options.go index 9f9939b5..e39ba56d 100644 --- a/internal/service/create/options.go +++ b/internal/service/create/options.go @@ -45,7 +45,7 @@ func (opts Options) Validate() error { return fmt.Errorf("%w: opts.TemplateOutput must not be empty", commonerrors.ErrInvalidOption) } - if opts.RegistryURL != "" && !strings.HasPrefix(opts.RegistryURL, "http") { + if !strings.HasPrefix(opts.RegistryURL, "http") { return fmt.Errorf("%w: opts.RegistryURL does not start with http(s)", commonerrors.ErrInvalidOption) } From eda8d793a750cc2c0dcd91d29d7fdf82d1cc9b34 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Tue, 24 Sep 2024 12:59:05 +0200 Subject: [PATCH 25/40] Fix E2E tests --- tests/e2e/create/create_test.go | 37 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 792bed69..7ba61b3b 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -42,19 +42,22 @@ var _ = Describe("Test 'create' command", Ordered, func() { invalidModuleConfigFile := "./testdata/module-config-missing-required.yaml" templateOutputPath := "/tmp/template.yaml" - - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked without any args", func() { - cmd = createCmd{} - }) - - It("Then the command should fail", func() { - err := cmd.execute() - Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - }) - }) + gitRemote := "https://github.com/kyma-project/template-operator" + + // TODO: Add a test with empty security + // test should be removed: module-config-file has the default value of module-config.yaml + // Context("Given 'modulectl create' command", func() { + // var cmd createCmd + // It("When invoked without any args", func() { + // cmd = createCmd{} + // }) + // + // It("Then the command should fail", func() { + // err := cmd.execute() + // Expect(err).Should(HaveOccurred()) + // Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) + // }) + // }) Context("Given 'modulectl create' command", func() { var cmd createCmd @@ -81,7 +84,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { It("Then the command should fail", func() { err := cmd.execute() Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("Error: field is required")) + Expect(err.Error()).Should(ContainSubstring("invalid Option: opts.ModuleName must not be empty")) }) }) @@ -108,6 +111,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { registry: ociRegistry, insecure: true, output: templateOutputPath, + gitRemote: gitRemote, } }) It("Then the command should succeed", func() { @@ -136,7 +140,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(repo.Object["type"]).To(Equal(ocireg.Type)) By("And descriptor.component.resources should be correct") - Expect(descriptor.Resources).To(HaveLen(2)) + Expect(descriptor.Resources).To(HaveLen(3)) resource := descriptor.Resources[0] Expect(resource.Name).To(Equal("template-operator")) Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) @@ -201,7 +205,8 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/subprojects", "false")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", "**/test/**,**/*_test.go")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", + "**/test/**,**/*_test.go")) }) }) From 4362d8f9f1f93809a10ad850e1e9a936123e5345 Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Tue, 24 Sep 2024 14:03:36 +0200 Subject: [PATCH 26/40] Add test case for missing security (still not passing) --- tests/e2e/create/create_test.go | 136 ++++++++++++++++-- .../module-config-missing-security.yaml | 7 + 2 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 tests/e2e/create/testdata/module-config-missing-security.yaml diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 7ba61b3b..2c131bce 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -45,19 +45,18 @@ var _ = Describe("Test 'create' command", Ordered, func() { gitRemote := "https://github.com/kyma-project/template-operator" // TODO: Add a test with empty security - // test should be removed: module-config-file has the default value of module-config.yaml - // Context("Given 'modulectl create' command", func() { - // var cmd createCmd - // It("When invoked without any args", func() { - // cmd = createCmd{} - // }) - // - // It("Then the command should fail", func() { - // err := cmd.execute() - // Expect(err).Should(HaveOccurred()) - // Expect(err.Error()).Should(ContainSubstring("Error: \"--module-config-file\" flag is required")) - // }) - // }) + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked without any args", func() { + cmd = createCmd{} + }) + + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("failed to read file module-config.yaml: open module-config.yaml: no such file or directory")) + }) + }) Context("Given 'modulectl create' command", func() { var cmd createCmd @@ -70,7 +69,9 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(cmd.execute()).To(Succeed()) By("And no module template file should be generated") - Expect(filesIn("./testdata/template-operator/")).Should(Not(ContainElement("template.yaml"))) + currentDir, err := os.Getwd() + Expect(err).ToNot(HaveOccurred()) + Expect(filesIn(currentDir)).Should(Not(ContainElement("template.yaml"))) }) }) @@ -224,6 +225,113 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(err.Error()).Should(ContainSubstring("could not push component version: component version already exists")) }) }) + + Context("Given 'modulectl create' command with no security option", func() { + var cmd createCmd + It("When invoked with existing '--registry' and '--insecure' flag", func() { + cmd = createCmd{ + moduleConfigFile: validModuleConfigFile, + registry: ociRegistry, + insecure: true, + output: templateOutputPath, + gitRemote: gitRemote, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And module template file should be generated") + Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutputPath) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + Expect(descriptor.SchemaVersion()).To(Equal(compdescv2.SchemaVersion)) + + By("And annotations should be correct") + annotations := template.Annotations + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal(moduleTemplateVersion)) + Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) + + By("And descriptor.component.repositoryContexts should be correct") + Expect(descriptor.RepositoryContexts).To(HaveLen(1)) + repo := descriptor.GetEffectiveRepositoryContext() + Expect(repo.Object["baseUrl"]).To(Equal(ociRegistry)) + Expect(repo.Object["componentNameMapping"]).To(Equal(string(ocmocireg.OCIRegistryURLPathMapping))) + Expect(repo.Object["type"]).To(Equal(ocireg.Type)) + + By("And descriptor.component.resources should be correct") + Expect(descriptor.Resources).To(HaveLen(3)) + resource := descriptor.Resources[0] + Expect(resource.Name).To(Equal("template-operator")) + Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) + Expect(resource.Type).To(Equal("ociArtifact")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + resource = descriptor.Resources[1] + Expect(resource.Name).To(Equal("raw-manifest")) + Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) + Expect(resource.Type).To(Equal("directory")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + resource = descriptor.Resources[2] + Expect(resource.Name).To(Equal("default-cr")) + Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) + Expect(resource.Type).To(Equal("directory")) + Expect(resource.Version).To(Equal(moduleTemplateVersion)) + + By("And descriptor.component.resources[0].access should be correct") + resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) + Expect(err).ToNot(HaveOccurred()) + ociArtifactAccessSpec, ok := resourceAccessSpec0.(*ociartifact.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(ociArtifactAccessSpec.GetType()).To(Equal(ociartifact.Type)) + Expect(ociArtifactAccessSpec.ImageReference).To(Equal("europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0")) + + By("And descriptor.component.resources[1].access should be correct") + resourceAccessSpec1, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) + Expect(err).ToNot(HaveOccurred()) + localBlobAccessSpec, ok := resourceAccessSpec1.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + Expect(localBlobAccessSpec.MediaType).To(Equal("application/x-tar")) + + By("And descriptor.component.resources[2].access should be correct") + defaultCRResourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[2].Access) + Expect(err).ToNot(HaveOccurred()) + defaultCRAccessSpec, ok := defaultCRResourceAccessSpec.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(defaultCRAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(defaultCRAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + Expect(defaultCRAccessSpec.MediaType).To(Equal("application/x-tar")) + + By("And descriptor.component.sources should be correct") + Expect(len(descriptor.Sources)).To(Equal(1)) + source := descriptor.Sources[0] + sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) + Expect(err).ToNot(HaveOccurred()) + githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(github.Type).To(Equal(githubAccessSpec.Type)) + Expect(githubAccessSpec.RepoURL).To(Equal("https://github.com/kyma-project/template-operator")) + + By("And spec.mandatory should be false") + Expect(template.Spec.Mandatory).To(BeFalse()) + + By("And security scan labels should be correct") + secScanLabels := flatten(descriptor.Sources[0].Labels) + Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "HEAD")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/rc-tag", "1.0.0")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/subprojects", "false")) + Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", + "**/test/**,**/*_test.go")) + }) + }) }) // Test helper functions diff --git a/tests/e2e/create/testdata/module-config-missing-security.yaml b/tests/e2e/create/testdata/module-config-missing-security.yaml new file mode 100644 index 00000000..a6c4bd45 --- /dev/null +++ b/tests/e2e/create/testdata/module-config-missing-security.yaml @@ -0,0 +1,7 @@ +name: kyma-project.io/module/template-operator +channel: regular +version: 1.0.1 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml +defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml +annotations: + operator.kyma-project.io/doc-url: https://kyma-project.io From a61acdf86c53e99d0b8ea3d39815e0e80fad4934 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 14:35:15 +0200 Subject: [PATCH 27/40] add more testdata --- tests/e2e/create/create_test.go | 75 ++++++++++++++++--- .../module-config-missing-required.yaml | 7 -- .../moduleconfig/invalid/missing-channel.yaml | 3 + .../invalid/missing-manifest.yaml | 3 + .../moduleconfig/invalid/missing-name.yaml | 3 + .../moduleconfig/invalid/missing-version.yaml | 3 + .../testdata/moduleconfig/valid/minimal.yaml | 4 + .../valid/with-annotations.yaml} | 2 - .../valid/with-defaultcr.yaml} | 4 +- .../moduleconfig/valid/with-security.yaml | 5 ++ 10 files changed, 86 insertions(+), 23 deletions(-) delete mode 100644 tests/e2e/create/testdata/module-config-missing-required.yaml create mode 100644 tests/e2e/create/testdata/moduleconfig/invalid/missing-channel.yaml create mode 100644 tests/e2e/create/testdata/moduleconfig/invalid/missing-manifest.yaml create mode 100644 tests/e2e/create/testdata/moduleconfig/invalid/missing-name.yaml create mode 100644 tests/e2e/create/testdata/moduleconfig/invalid/missing-version.yaml create mode 100644 tests/e2e/create/testdata/moduleconfig/valid/minimal.yaml rename tests/e2e/create/testdata/{module-config-valid.yaml => moduleconfig/valid/with-annotations.yaml} (64%) rename tests/e2e/create/testdata/{module-config-missing-security.yaml => moduleconfig/valid/with-defaultcr.yaml} (76%) create mode 100644 tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 2c131bce..be407109 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -24,6 +24,22 @@ import ( . "github.com/onsi/gomega" ) +const ( + testdataDir = "./testdata/moduleconfig/" + + validConfigs = testdataDir + "valid/" + minimalConfig = validConfigs + "minimal.yaml" + withAnnotationsConfig = validConfigs + "with-annotations.yaml" + withDefaultCrConfig = validConfigs + "with-defaultcr.yaml" + withSecurityConfig = validConfigs + "with-security.yaml" + + invalidConfigs = testdataDir + "invalid/" + missingNameConfig = invalidConfigs + "missing-name.yaml" + missingChannelConfig = invalidConfigs + "missing-channel.yaml" + missingVersionConfig = invalidConfigs + "missing-version.yaml" + missingManifestConfig = invalidConfigs + "missing-manifest.yaml" +) + var _ = Describe("Test 'create' command", Ordered, func() { // _ = os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") // _ = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") @@ -36,11 +52,6 @@ var _ = Describe("Test 'create' command", Ordered, func() { ociRegistry := "http://k3d-oci.localhost:5001" moduleTemplateVersion := "1.0.0" - - // TODO build module-config file in tests? - validModuleConfigFile := "./testdata/module-config-valid.yaml" - invalidModuleConfigFile := "./testdata/module-config-missing-required.yaml" - templateOutputPath := "/tmp/template.yaml" gitRemote := "https://github.com/kyma-project/template-operator" @@ -62,7 +73,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { var cmd createCmd It("When invoked with '--module-config-file' using valid file", func() { cmd = createCmd{ - moduleConfigFile: validModuleConfigFile, + moduleConfigFile: minimalConfig, } }) It("Then the command should succeed", func() { @@ -77,9 +88,9 @@ var _ = Describe("Test 'create' command", Ordered, func() { Context("Given 'modulectl create' command", func() { var cmd createCmd - It("When invoked with '--module-config-file' using file with missing required fields", func() { + It("When invoked with '--module-config-file' using file with missing name", func() { cmd = createCmd{ - moduleConfigFile: invalidModuleConfigFile, + moduleConfigFile: missingNameConfig, } }) It("Then the command should fail", func() { @@ -89,11 +100,53 @@ var _ = Describe("Test 'create' command", Ordered, func() { }) }) + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-config-file' using file with missing channel", func() { + cmd = createCmd{ + moduleConfigFile: missingChannelConfig, + } + }) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("invalid Option: opts.ModuleChannel must not be empty")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-config-file' using file with missing version", func() { + cmd = createCmd{ + moduleConfigFile: missingVersionConfig, + } + }) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("invalid Option: opts.ModuleVersion must not be empty")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-config-file' using file with missing manifest", func() { + cmd = createCmd{ + moduleConfigFile: missingManifestConfig, + } + }) + It("Then the command should fail", func() { + err := cmd.execute() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("invalid Option: opts.ModuleManifest must not be empty")) + }) + }) + Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked with existing '--registry' and missing '--insecure' flag", func() { cmd = createCmd{ - moduleConfigFile: validModuleConfigFile, + moduleConfigFile: minimalConfig, registry: ociRegistry, } }) @@ -108,7 +161,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { var cmd createCmd It("When invoked with existing '--registry' and '--insecure' flag", func() { cmd = createCmd{ - moduleConfigFile: validModuleConfigFile, + moduleConfigFile: minimalConfig, registry: ociRegistry, insecure: true, output: templateOutputPath, @@ -215,7 +268,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { var cmd createCmd It("When invoked with same version that already exists in the registry", func() { cmd = createCmd{ - moduleConfigFile: validModuleConfigFile, + moduleConfigFile: minimalConfig, registry: ociRegistry, insecure: true, } diff --git a/tests/e2e/create/testdata/module-config-missing-required.yaml b/tests/e2e/create/testdata/module-config-missing-required.yaml deleted file mode 100644 index 9e48649c..00000000 --- a/tests/e2e/create/testdata/module-config-missing-required.yaml +++ /dev/null @@ -1,7 +0,0 @@ -channel: regular -version: 1.0.0 -manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml -security: sec-scanners-config.yaml -defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml -annotations: - operator.kyma-project.io/doc-url: https://kyma-project.io diff --git a/tests/e2e/create/testdata/moduleconfig/invalid/missing-channel.yaml b/tests/e2e/create/testdata/moduleconfig/invalid/missing-channel.yaml new file mode 100644 index 00000000..13f18142 --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/invalid/missing-channel.yaml @@ -0,0 +1,3 @@ +name: kyma-project.io/module/template-operator +version: 1.0.1 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml diff --git a/tests/e2e/create/testdata/moduleconfig/invalid/missing-manifest.yaml b/tests/e2e/create/testdata/moduleconfig/invalid/missing-manifest.yaml new file mode 100644 index 00000000..f97ebd04 --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/invalid/missing-manifest.yaml @@ -0,0 +1,3 @@ +name: kyma-project.io/module/template-operator +channel: regular +version: 1.0.1 diff --git a/tests/e2e/create/testdata/moduleconfig/invalid/missing-name.yaml b/tests/e2e/create/testdata/moduleconfig/invalid/missing-name.yaml new file mode 100644 index 00000000..88697720 --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/invalid/missing-name.yaml @@ -0,0 +1,3 @@ +channel: regular +version: 1.0.1 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml diff --git a/tests/e2e/create/testdata/moduleconfig/invalid/missing-version.yaml b/tests/e2e/create/testdata/moduleconfig/invalid/missing-version.yaml new file mode 100644 index 00000000..73f440db --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/invalid/missing-version.yaml @@ -0,0 +1,3 @@ +name: kyma-project.io/module/template-operator +channel: regular +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml diff --git a/tests/e2e/create/testdata/moduleconfig/valid/minimal.yaml b/tests/e2e/create/testdata/moduleconfig/valid/minimal.yaml new file mode 100644 index 00000000..97ae1545 --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/valid/minimal.yaml @@ -0,0 +1,4 @@ +name: kyma-project.io/module/template-operator +channel: regular +version: 1.0.0 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml diff --git a/tests/e2e/create/testdata/module-config-valid.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml similarity index 64% rename from tests/e2e/create/testdata/module-config-valid.yaml rename to tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml index c36fc1bf..4f7cb8cc 100644 --- a/tests/e2e/create/testdata/module-config-valid.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml @@ -2,7 +2,5 @@ name: kyma-project.io/module/template-operator channel: regular version: 1.0.0 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml -security: sec-scanners-config.yaml -defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml annotations: operator.kyma-project.io/doc-url: https://kyma-project.io diff --git a/tests/e2e/create/testdata/module-config-missing-security.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml similarity index 76% rename from tests/e2e/create/testdata/module-config-missing-security.yaml rename to tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml index a6c4bd45..230b4856 100644 --- a/tests/e2e/create/testdata/module-config-missing-security.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml @@ -1,7 +1,5 @@ name: kyma-project.io/module/template-operator channel: regular -version: 1.0.1 +version: 1.0.0 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml -annotations: - operator.kyma-project.io/doc-url: https://kyma-project.io diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml new file mode 100644 index 00000000..1935ac4c --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml @@ -0,0 +1,5 @@ +name: kyma-project.io/module/template-operator +channel: regular +version: 1.0.0 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml +security: sec-scanners-config.yaml From 6e86073ba29255674a13d1d7152f7832289e915c Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 14:42:59 +0200 Subject: [PATCH 28/40] use new testdata --- tests/e2e/create/create_test.go | 107 ------------------ .../moduleconfig/valid/with-annotations.yaml | 2 +- .../moduleconfig/valid/with-defaultcr.yaml | 2 +- .../moduleconfig/valid/with-security.yaml | 2 +- 4 files changed, 3 insertions(+), 110 deletions(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index be407109..5b3433d3 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -278,113 +278,6 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(err.Error()).Should(ContainSubstring("could not push component version: component version already exists")) }) }) - - Context("Given 'modulectl create' command with no security option", func() { - var cmd createCmd - It("When invoked with existing '--registry' and '--insecure' flag", func() { - cmd = createCmd{ - moduleConfigFile: validModuleConfigFile, - registry: ociRegistry, - insecure: true, - output: templateOutputPath, - gitRemote: gitRemote, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And module template file should be generated") - Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) - }) - It("Then module template should contain the expected content", func() { - template, err := readModuleTemplate(templateOutputPath) - Expect(err).ToNot(HaveOccurred()) - descriptor := getDescriptor(template) - Expect(descriptor).ToNot(BeNil()) - Expect(descriptor.SchemaVersion()).To(Equal(compdescv2.SchemaVersion)) - - By("And annotations should be correct") - annotations := template.Annotations - Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal(moduleTemplateVersion)) - Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) - - By("And descriptor.component.repositoryContexts should be correct") - Expect(descriptor.RepositoryContexts).To(HaveLen(1)) - repo := descriptor.GetEffectiveRepositoryContext() - Expect(repo.Object["baseUrl"]).To(Equal(ociRegistry)) - Expect(repo.Object["componentNameMapping"]).To(Equal(string(ocmocireg.OCIRegistryURLPathMapping))) - Expect(repo.Object["type"]).To(Equal(ocireg.Type)) - - By("And descriptor.component.resources should be correct") - Expect(descriptor.Resources).To(HaveLen(3)) - resource := descriptor.Resources[0] - Expect(resource.Name).To(Equal("template-operator")) - Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) - Expect(resource.Type).To(Equal("ociArtifact")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) - - resource = descriptor.Resources[1] - Expect(resource.Name).To(Equal("raw-manifest")) - Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) - Expect(resource.Type).To(Equal("directory")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) - - resource = descriptor.Resources[2] - Expect(resource.Name).To(Equal("default-cr")) - Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) - Expect(resource.Type).To(Equal("directory")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) - - By("And descriptor.component.resources[0].access should be correct") - resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) - Expect(err).ToNot(HaveOccurred()) - ociArtifactAccessSpec, ok := resourceAccessSpec0.(*ociartifact.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(ociArtifactAccessSpec.GetType()).To(Equal(ociartifact.Type)) - Expect(ociArtifactAccessSpec.ImageReference).To(Equal("europe-docker.pkg.dev/kyma-project/prod/template-operator:1.0.0")) - - By("And descriptor.component.resources[1].access should be correct") - resourceAccessSpec1, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) - Expect(err).ToNot(HaveOccurred()) - localBlobAccessSpec, ok := resourceAccessSpec1.(*localblob.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) - Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) - Expect(localBlobAccessSpec.MediaType).To(Equal("application/x-tar")) - - By("And descriptor.component.resources[2].access should be correct") - defaultCRResourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[2].Access) - Expect(err).ToNot(HaveOccurred()) - defaultCRAccessSpec, ok := defaultCRResourceAccessSpec.(*localblob.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(defaultCRAccessSpec.GetType()).To(Equal(localblob.Type)) - Expect(defaultCRAccessSpec.LocalReference).To(ContainSubstring("sha256:")) - Expect(defaultCRAccessSpec.MediaType).To(Equal("application/x-tar")) - - By("And descriptor.component.sources should be correct") - Expect(len(descriptor.Sources)).To(Equal(1)) - source := descriptor.Sources[0] - sourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(source.Access) - Expect(err).ToNot(HaveOccurred()) - githubAccessSpec, ok := sourceAccessSpec.(*github.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(github.Type).To(Equal(githubAccessSpec.Type)) - Expect(githubAccessSpec.RepoURL).To(Equal("https://github.com/kyma-project/template-operator")) - - By("And spec.mandatory should be false") - Expect(template.Spec.Mandatory).To(BeFalse()) - - By("And security scan labels should be correct") - secScanLabels := flatten(descriptor.Sources[0].Labels) - Expect(secScanLabels).To(HaveKeyWithValue("git.kyma-project.io/ref", "HEAD")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/rc-tag", "1.0.0")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/language", "golang-mod")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/dev-branch", "main")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/subprojects", "false")) - Expect(secScanLabels).To(HaveKeyWithValue("scan.security.kyma-project.io/exclude", - "**/test/**,**/*_test.go")) - }) - }) }) // Test helper functions diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml index 4f7cb8cc..a81f4a88 100644 --- a/tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-annotations.yaml @@ -1,6 +1,6 @@ name: kyma-project.io/module/template-operator channel: regular -version: 1.0.0 +version: 1.0.1 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml annotations: operator.kyma-project.io/doc-url: https://kyma-project.io diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml index 230b4856..791579bb 100644 --- a/tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-defaultcr.yaml @@ -1,5 +1,5 @@ name: kyma-project.io/module/template-operator channel: regular -version: 1.0.0 +version: 1.0.2 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml defaultCR: https://github.com/kyma-project/template-operator/releases/download/1.0.1/default-sample-cr.yaml diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml index 1935ac4c..f2bfe885 100644 --- a/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-security.yaml @@ -1,5 +1,5 @@ name: kyma-project.io/module/template-operator channel: regular -version: 1.0.0 +version: 1.0.3 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml security: sec-scanners-config.yaml From 583f7a16893c548dd1084276e145ecc54fdf8b59 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 14:50:58 +0200 Subject: [PATCH 29/40] clean-up --- .github/workflows/test-e2e-create.yml | 4 -- tests/e2e/create/create_test.go | 71 +++++++++++---------------- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/.github/workflows/test-e2e-create.yml b/.github/workflows/test-e2e-create.yml index 11d46443..58701af8 100644 --- a/.github/workflows/test-e2e-create.yml +++ b/.github/workflows/test-e2e-create.yml @@ -30,10 +30,6 @@ jobs: ls -la ./bin mv ./bin/modulectl-linux /usr/local/bin/modulectl timeout-minutes: 5 -# - name: Set template-operator github URL -# run: | -# cd ./template-operator -# echo "TEST_REPOSITORY_URL=$(git remote get-url origin)" >> "$GITHUB_ENV" - name: Install k3d and create registry run: | wget -qO - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=$K3D_VERSION bash diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 5b3433d3..560c5773 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -27,35 +27,24 @@ import ( const ( testdataDir = "./testdata/moduleconfig/" + invalidConfigs = testdataDir + "invalid/" + missingNameConfig = invalidConfigs + "missing-name.yaml" + missingChannelConfig = invalidConfigs + "missing-channel.yaml" + missingVersionConfig = invalidConfigs + "missing-version.yaml" + missingManifestConfig = invalidConfigs + "missing-manifest.yaml" + validConfigs = testdataDir + "valid/" minimalConfig = validConfigs + "minimal.yaml" withAnnotationsConfig = validConfigs + "with-annotations.yaml" withDefaultCrConfig = validConfigs + "with-defaultcr.yaml" withSecurityConfig = validConfigs + "with-security.yaml" - invalidConfigs = testdataDir + "invalid/" - missingNameConfig = invalidConfigs + "missing-name.yaml" - missingChannelConfig = invalidConfigs + "missing-channel.yaml" - missingVersionConfig = invalidConfigs + "missing-version.yaml" - missingManifestConfig = invalidConfigs + "missing-manifest.yaml" + ociRegistry = "http://k3d-oci.localhost:5001" + templateOutputPath = "/tmp/template.yaml" + gitRemote = "https://github.com/kyma-project/template-operator" ) var _ = Describe("Test 'create' command", Ordered, func() { - // _ = os.Setenv("OCI_REPOSITORY_URL", "http://k3d-oci.localhost:5001") - // _ = os.Setenv("MODULE_TEMPLATE_PATH", "/tmp/module-config-template.yaml") - // _ = os.Setenv("MODULE_TEMPLATE_VERSION", "1.0.0") - - // ociRegistry := os.Getenv("OCI_REPOSITORY_URL") - // testRepoURL := os.Getenv("TEST_REPOSITORY_URL") - // templateOutputPath := os.Getenv("MODULE_TEMPLATE_PATH") - // moduleTemplateVersion := os.Getenv("MODULE_TEMPLATE_VERSION") - - ociRegistry := "http://k3d-oci.localhost:5001" - moduleTemplateVersion := "1.0.0" - templateOutputPath := "/tmp/template.yaml" - gitRemote := "https://github.com/kyma-project/template-operator" - - // TODO: Add a test with empty security Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked without any args", func() { @@ -69,23 +58,6 @@ var _ = Describe("Test 'create' command", Ordered, func() { }) }) - Context("Given 'modulectl create' command", func() { - var cmd createCmd - It("When invoked with '--module-config-file' using valid file", func() { - cmd = createCmd{ - moduleConfigFile: minimalConfig, - } - }) - It("Then the command should succeed", func() { - Expect(cmd.execute()).To(Succeed()) - - By("And no module template file should be generated") - currentDir, err := os.Getwd() - Expect(err).ToNot(HaveOccurred()) - Expect(filesIn(currentDir)).Should(Not(ContainElement("template.yaml"))) - }) - }) - Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked with '--module-config-file' using file with missing name", func() { @@ -142,6 +114,23 @@ var _ = Describe("Test 'create' command", Ordered, func() { }) }) + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with '--module-config-file' using valid file", func() { + cmd = createCmd{ + moduleConfigFile: minimalConfig, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And no module template file should be generated") + currentDir, err := os.Getwd() + Expect(err).ToNot(HaveOccurred()) + Expect(filesIn(currentDir)).Should(Not(ContainElement("template.yaml"))) + }) + }) + Context("Given 'modulectl create' command", func() { var cmd createCmd It("When invoked with existing '--registry' and missing '--insecure' flag", func() { @@ -183,7 +172,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { By("And annotations should be correct") annotations := template.Annotations - Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal(moduleTemplateVersion)) + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal("1.0.0")) Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) By("And descriptor.component.repositoryContexts should be correct") @@ -199,19 +188,19 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(resource.Name).To(Equal("template-operator")) Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) Expect(resource.Type).To(Equal("ociArtifact")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) + Expect(resource.Version).To(Equal("1.0.0")) resource = descriptor.Resources[1] Expect(resource.Name).To(Equal("raw-manifest")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) Expect(resource.Type).To(Equal("directory")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) + Expect(resource.Version).To(Equal("1.0.0")) resource = descriptor.Resources[2] Expect(resource.Name).To(Equal("default-cr")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) Expect(resource.Type).To(Equal("directory")) - Expect(resource.Version).To(Equal(moduleTemplateVersion)) + Expect(resource.Version).To(Equal("1.0.0")) By("And descriptor.component.resources[0].access should be correct") resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) From b7e90dfd5e32b0e02a5919cf0854e1f8ca81098a Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 15:32:56 +0200 Subject: [PATCH 30/40] add testcases for different valid module-configs --- tests/e2e/create/create_test.go | 179 +++++++++++++++--- .../moduleconfig/valid/with-mandatory.yaml | 5 + 2 files changed, 158 insertions(+), 26 deletions(-) create mode 100644 tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 560c5773..9a602b11 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -3,14 +3,14 @@ package create_test import ( + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" "io/fs" "os" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" "github.com/open-component-model/ocm/pkg/contexts/ocm" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" ocmmetav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" @@ -38,6 +38,7 @@ const ( withAnnotationsConfig = validConfigs + "with-annotations.yaml" withDefaultCrConfig = validConfigs + "with-defaultcr.yaml" withSecurityConfig = validConfigs + "with-security.yaml" + withMandatoryConfig = validConfigs + "with-mandatory.yaml" ociRegistry = "http://k3d-oci.localhost:5001" templateOutputPath = "/tmp/template.yaml" @@ -148,13 +149,12 @@ var _ = Describe("Test 'create' command", Ordered, func() { Context("Given 'modulectl create' command", func() { var cmd createCmd - It("When invoked with existing '--registry' and '--insecure' flag", func() { + It("When invoked with minimal valid module-config", func() { cmd = createCmd{ moduleConfigFile: minimalConfig, registry: ociRegistry, insecure: true, output: templateOutputPath, - gitRemote: gitRemote, } }) It("Then the command should succeed", func() { @@ -183,25 +183,149 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(repo.Object["type"]).To(Equal(ocireg.Type)) By("And descriptor.component.resources should be correct") - Expect(descriptor.Resources).To(HaveLen(3)) + Expect(descriptor.Resources).To(HaveLen(1)) resource := descriptor.Resources[0] - Expect(resource.Name).To(Equal("template-operator")) - Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) - Expect(resource.Type).To(Equal("ociArtifact")) - Expect(resource.Version).To(Equal("1.0.0")) - - resource = descriptor.Resources[1] Expect(resource.Name).To(Equal("raw-manifest")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) Expect(resource.Type).To(Equal("directory")) Expect(resource.Version).To(Equal("1.0.0")) - resource = descriptor.Resources[2] + By("And descriptor.component.resources[0].access should be correct") + resourceAccessSpec1, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) + Expect(err).ToNot(HaveOccurred()) + localBlobAccessSpec, ok := resourceAccessSpec1.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(localBlobAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + Expect(localBlobAccessSpec.MediaType).To(Equal("application/x-tar")) + + By("And descriptor.component.sources should be empty") + Expect(len(descriptor.Sources)).To(Equal(0)) + + By("And spec.mandatory should be false") + Expect(template.Spec.Mandatory).To(BeFalse()) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with same version that already exists in the registry", func() { + cmd = createCmd{ + moduleConfigFile: minimalConfig, + registry: ociRegistry, + insecure: true, + } + }) + It("Then the command should fail with same version exists message", func() { + err := cmd.execute() + Expect(err.Error()).Should(ContainSubstring("could not push component version: component version already exists")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with valid module-config containing annotations and different version", func() { + cmd = createCmd{ + moduleConfigFile: withAnnotationsConfig, + registry: ociRegistry, + insecure: true, + output: templateOutputPath, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And module template file should be generated") + Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutputPath) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + + By("And new annotation should be correctly added") + annotations := template.Annotations + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal("1.0.0")) + Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) + Expect(annotations["operator.kyma-project.io/doc-url"]).To(Equal("https://kyma-project.io")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with valid module-config containing default-cr and different version", func() { + cmd = createCmd{ + moduleConfigFile: withDefaultCrConfig, + registry: ociRegistry, + insecure: true, + output: templateOutputPath, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And module template file should be generated") + Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutputPath) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + + By("And descriptor.component.resources should be correct") + Expect(descriptor.Resources).To(HaveLen(2)) + resource := descriptor.Resources[1] Expect(resource.Name).To(Equal("default-cr")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) Expect(resource.Type).To(Equal("directory")) Expect(resource.Version).To(Equal("1.0.0")) + By("And descriptor.component.resources[1].access should be correct") + defaultCRResourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) + Expect(err).ToNot(HaveOccurred()) + defaultCRAccessSpec, ok := defaultCRResourceAccessSpec.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + Expect(defaultCRAccessSpec.GetType()).To(Equal(localblob.Type)) + Expect(defaultCRAccessSpec.LocalReference).To(ContainSubstring("sha256:")) + Expect(defaultCRAccessSpec.MediaType).To(Equal("application/x-tar")) + }) + }) + + Context("Given 'modulectl create' command", func() { + var cmd createCmd + It("When invoked with valid module-config containing security-scanner-config and different version, and the git-remote flag", func() { + cmd = createCmd{ + moduleConfigFile: withSecurityConfig, + registry: ociRegistry, + insecure: true, + output: templateOutputPath, + gitRemote: gitRemote, + } + }) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And module template file should be generated") + Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutputPath) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + + By("And descriptor.component.resources should be correct") + Expect(descriptor.Resources).To(HaveLen(2)) + resource := descriptor.Resources[0] + Expect(resource.Name).To(Equal("template-operator")) + Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) + Expect(resource.Type).To(Equal("ociArtifact")) + Expect(resource.Version).To(Equal("1.0.0")) + resource = descriptor.Resources[1] + Expect(resource.Name).To(Equal("raw-manifest")) + By("And descriptor.component.resources[0].access should be correct") resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) Expect(err).ToNot(HaveOccurred()) @@ -219,15 +343,6 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(localBlobAccessSpec.LocalReference).To(ContainSubstring("sha256:")) Expect(localBlobAccessSpec.MediaType).To(Equal("application/x-tar")) - By("And descriptor.component.resources[2].access should be correct") - defaultCRResourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[2].Access) - Expect(err).ToNot(HaveOccurred()) - defaultCRAccessSpec, ok := defaultCRResourceAccessSpec.(*localblob.AccessSpec) - Expect(ok).To(BeTrue()) - Expect(defaultCRAccessSpec.GetType()).To(Equal(localblob.Type)) - Expect(defaultCRAccessSpec.LocalReference).To(ContainSubstring("sha256:")) - Expect(defaultCRAccessSpec.MediaType).To(Equal("application/x-tar")) - By("And descriptor.component.sources should be correct") Expect(len(descriptor.Sources)).To(Equal(1)) source := descriptor.Sources[0] @@ -255,16 +370,28 @@ var _ = Describe("Test 'create' command", Ordered, func() { Context("Given 'modulectl create' command", func() { var cmd createCmd - It("When invoked with same version that already exists in the registry", func() { + It("When invoked with valid module-config containing mandatory true and different version", func() { cmd = createCmd{ - moduleConfigFile: minimalConfig, + moduleConfigFile: withMandatoryConfig, registry: ociRegistry, insecure: true, + output: templateOutputPath, } }) - It("Then the command should fail with same version exists message", func() { - err := cmd.execute() - Expect(err.Error()).Should(ContainSubstring("could not push component version: component version already exists")) + It("Then the command should succeed", func() { + Expect(cmd.execute()).To(Succeed()) + + By("And module template file should be generated") + Expect(filesIn("/tmp/")).Should(ContainElement("template.yaml")) + }) + It("Then module template should contain the expected content", func() { + template, err := readModuleTemplate(templateOutputPath) + Expect(err).ToNot(HaveOccurred()) + descriptor := getDescriptor(template) + Expect(descriptor).ToNot(BeNil()) + + By("And spec.mandatory should be true") + Expect(template.Spec.Mandatory).To(BeTrue()) }) }) }) diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml new file mode 100644 index 00000000..acad1e86 --- /dev/null +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml @@ -0,0 +1,5 @@ +name: kyma-project.io/module/template-operator +channel: regular +version: 1.0.0 +manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml +mandatory: true \ No newline at end of file From 4b9aa46f8ae8709bf5939ec4f4df277b6a3f7d75 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 15:33:53 +0200 Subject: [PATCH 31/40] bump mandatory version --- .../e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml index acad1e86..93358dc5 100644 --- a/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml @@ -1,5 +1,5 @@ name: kyma-project.io/module/template-operator channel: regular -version: 1.0.0 +version: 1.0.4 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml mandatory: true \ No newline at end of file From 53679d81b1d4cce2e9b97439931cbe3597fefbbb Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 15:36:39 +0200 Subject: [PATCH 32/40] move consts --- tests/e2e/create/create_suite_test.go | 21 +++++++++++++++++++++ tests/e2e/create/create_test.go | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/e2e/create/create_suite_test.go b/tests/e2e/create/create_suite_test.go index 8a7f3077..48a67953 100644 --- a/tests/e2e/create/create_suite_test.go +++ b/tests/e2e/create/create_suite_test.go @@ -17,6 +17,27 @@ func Test_Create(t *testing.T) { RunSpecs(t, "'Create' Command Test Suite") } +const ( + testdataDir = "./testdata/moduleconfig/" + + invalidConfigs = testdataDir + "invalid/" + missingNameConfig = invalidConfigs + "missing-name.yaml" + missingChannelConfig = invalidConfigs + "missing-channel.yaml" + missingVersionConfig = invalidConfigs + "missing-version.yaml" + missingManifestConfig = invalidConfigs + "missing-manifest.yaml" + + validConfigs = testdataDir + "valid/" + minimalConfig = validConfigs + "minimal.yaml" + withAnnotationsConfig = validConfigs + "with-annotations.yaml" + withDefaultCrConfig = validConfigs + "with-defaultcr.yaml" + withSecurityConfig = validConfigs + "with-security.yaml" + withMandatoryConfig = validConfigs + "with-mandatory.yaml" + + ociRegistry = "http://k3d-oci.localhost:5001" + templateOutputPath = "/tmp/template.yaml" + gitRemote = "https://github.com/kyma-project/template-operator" +) + // Command wrapper for `modulectl create` type createCmd struct { diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 9a602b11..dc7ab52b 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -24,27 +24,6 @@ import ( . "github.com/onsi/gomega" ) -const ( - testdataDir = "./testdata/moduleconfig/" - - invalidConfigs = testdataDir + "invalid/" - missingNameConfig = invalidConfigs + "missing-name.yaml" - missingChannelConfig = invalidConfigs + "missing-channel.yaml" - missingVersionConfig = invalidConfigs + "missing-version.yaml" - missingManifestConfig = invalidConfigs + "missing-manifest.yaml" - - validConfigs = testdataDir + "valid/" - minimalConfig = validConfigs + "minimal.yaml" - withAnnotationsConfig = validConfigs + "with-annotations.yaml" - withDefaultCrConfig = validConfigs + "with-defaultcr.yaml" - withSecurityConfig = validConfigs + "with-security.yaml" - withMandatoryConfig = validConfigs + "with-mandatory.yaml" - - ociRegistry = "http://k3d-oci.localhost:5001" - templateOutputPath = "/tmp/template.yaml" - gitRemote = "https://github.com/kyma-project/template-operator" -) - var _ = Describe("Test 'create' command", Ordered, func() { Context("Given 'modulectl create' command", func() { var cmd createCmd From 940bf014b4b64d2c58c0a9acb570ecd8b21c9abf Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 15:51:07 +0200 Subject: [PATCH 33/40] fix tests --- tests/e2e/create/create_test.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index dc7ab52b..da9c5596 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -90,7 +90,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { It("Then the command should fail", func() { err := cmd.execute() Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("invalid Option: opts.ModuleManifest must not be empty")) + Expect(err.Error()).Should(ContainSubstring("failed to parse module config: invalid Option: manifest path must not be empty: failed to value module config")) }) }) @@ -225,9 +225,13 @@ var _ = Describe("Test 'create' command", Ordered, func() { By("And new annotation should be correctly added") annotations := template.Annotations - Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal("1.0.0")) + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal("1.0.1")) Expect(annotations[shared.IsClusterScopedAnnotation]).To(Equal("false")) Expect(annotations["operator.kyma-project.io/doc-url"]).To(Equal("https://kyma-project.io")) + + By("And descriptor.component.resources should be correct") + resource := descriptor.Resources[0] + Expect(resource.Version).To(Equal("1.0.1")) }) }) @@ -253,13 +257,17 @@ var _ = Describe("Test 'create' command", Ordered, func() { descriptor := getDescriptor(template) Expect(descriptor).ToNot(BeNil()) + By("And annotation should have correct version") + annotations := template.Annotations + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal("1.0.2")) + By("And descriptor.component.resources should be correct") Expect(descriptor.Resources).To(HaveLen(2)) resource := descriptor.Resources[1] Expect(resource.Name).To(Equal("default-cr")) Expect(resource.Relation).To(Equal(ocmmetav1.LocalRelation)) Expect(resource.Type).To(Equal("directory")) - Expect(resource.Version).To(Equal("1.0.0")) + Expect(resource.Version).To(Equal("1.0.2")) By("And descriptor.component.resources[1].access should be correct") defaultCRResourceAccessSpec, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[1].Access) From 1e4c609e175ba233fba91080ddf63474a1ae3381 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 15:59:56 +0200 Subject: [PATCH 34/40] fix tests --- tests/e2e/create/create_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index da9c5596..f952e24f 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -309,7 +309,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(resource.Name).To(Equal("template-operator")) Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) Expect(resource.Type).To(Equal("ociArtifact")) - Expect(resource.Version).To(Equal("1.0.0")) + Expect(resource.Version).To(Equal("1.0.3")) resource = descriptor.Resources[1] Expect(resource.Name).To(Equal("raw-manifest")) @@ -377,6 +377,10 @@ var _ = Describe("Test 'create' command", Ordered, func() { descriptor := getDescriptor(template) Expect(descriptor).ToNot(BeNil()) + By("And annotation should have correct version") + annotations := template.Annotations + Expect(annotations[shared.ModuleVersionAnnotation]).To(Equal("1.0.4")) + By("And spec.mandatory should be true") Expect(template.Spec.Mandatory).To(BeTrue()) }) From c557e161319b82ca020205e8d7f871eb2bb4d26f Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Tue, 24 Sep 2024 16:13:56 +0200 Subject: [PATCH 35/40] fix tests --- tests/e2e/create/create_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index f952e24f..6e664894 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -309,9 +309,10 @@ var _ = Describe("Test 'create' command", Ordered, func() { Expect(resource.Name).To(Equal("template-operator")) Expect(resource.Relation).To(Equal(ocmmetav1.ExternalRelation)) Expect(resource.Type).To(Equal("ociArtifact")) - Expect(resource.Version).To(Equal("1.0.3")) + Expect(resource.Version).To(Equal("1.0.0")) resource = descriptor.Resources[1] Expect(resource.Name).To(Equal("raw-manifest")) + Expect(resource.Version).To(Equal("1.0.3")) By("And descriptor.component.resources[0].access should be correct") resourceAccessSpec0, err := ocm.DefaultContext().AccessSpecForSpec(descriptor.Resources[0].Access) From d3bf27995294b3c47e38af60c541f552e6792e37 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 26 Sep 2024 10:08:15 +0200 Subject: [PATCH 36/40] fix merge diff --- internal/service/create/create_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/service/create/create_test.go b/internal/service/create/create_test.go index 5b41bbe2..40474d2a 100644 --- a/internal/service/create/create_test.go +++ b/internal/service/create/create_test.go @@ -33,7 +33,7 @@ func Test_CreateModule_ReturnsError_WhenModuleConfigFileIsEmpty(t *testing.T) { opts := newCreateOptionsBuilder().withModuleConfigFile("").build() - err = svc.CreateModule(opts) + err = svc.Run(opts) require.ErrorIs(t, err, commonerrors.ErrInvalidOption) require.Contains(t, err.Error(), "opts.ModuleConfigFile") @@ -46,7 +46,7 @@ func Test_CreateModule_ReturnsError_WhenOutIsNil(t *testing.T) { opts := newCreateOptionsBuilder().withOut(nil).build() - err = svc.CreateModule(opts) + err = svc.Run(opts) require.ErrorIs(t, err, commonerrors.ErrInvalidOption) require.Contains(t, err.Error(), "opts.Out") @@ -59,7 +59,7 @@ func Test_CreateModule_ReturnsError_WhenCredentialsIsInInvalidFormat(t *testing. opts := newCreateOptionsBuilder().withCredentials("user").build() - err = svc.CreateModule(opts) + err = svc.Run(opts) require.ErrorIs(t, err, commonerrors.ErrInvalidOption) require.Contains(t, err.Error(), "opts.Credentials") @@ -72,7 +72,7 @@ func Test_CreateModule_ReturnsError_WhenTemplateOutputIsEmpty(t *testing.T) { opts := newCreateOptionsBuilder().withTemplateOutput("").build() - err = svc.CreateModule(opts) + err = svc.Run(opts) require.ErrorIs(t, err, commonerrors.ErrInvalidOption) require.Contains(t, err.Error(), "opts.TemplateOutput") @@ -86,7 +86,7 @@ func Test_CreateModule_ReturnsError_WhenParseAndValidateModuleConfigReturnsError opts := newCreateOptionsBuilder().build() - err = svc.CreateModule(opts) + err = svc.Run(opts) require.Error(t, err) require.Contains(t, err.Error(), "failed to read module config file") From 497cc768d2441ae306525337907f6f2f72ad4bb1 Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 26 Sep 2024 10:09:13 +0200 Subject: [PATCH 37/40] new line --- .../e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml b/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml index 93358dc5..c35504c3 100644 --- a/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml +++ b/tests/e2e/create/testdata/moduleconfig/valid/with-mandatory.yaml @@ -2,4 +2,4 @@ name: kyma-project.io/module/template-operator channel: regular version: 1.0.4 manifest: https://github.com/kyma-project/template-operator/releases/download/1.0.1/template-operator.yaml -mandatory: true \ No newline at end of file +mandatory: true From 6551f9c1bc6d6280f394803c3abb2598c1dba74e Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 26 Sep 2024 10:15:32 +0200 Subject: [PATCH 38/40] fix e2e expected err --- tests/e2e/create/create_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/create/create_test.go b/tests/e2e/create/create_test.go index 6e664894..9423c189 100644 --- a/tests/e2e/create/create_test.go +++ b/tests/e2e/create/create_test.go @@ -90,7 +90,7 @@ var _ = Describe("Test 'create' command", Ordered, func() { It("Then the command should fail", func() { err := cmd.execute() Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring("failed to parse module config: invalid Option: manifest path must not be empty: failed to value module config")) + Expect(err.Error()).Should(ContainSubstring("failed to parse module config: failed to value module config: manifest path must not be empty: invalid Option")) }) }) From f46f869380784bce2794284a1f906e6691fe550b Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 26 Sep 2024 10:19:50 +0200 Subject: [PATCH 39/40] adapt coverage --- unit-test-coverage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-test-coverage.yaml b/unit-test-coverage.yaml index 9a656c9b..80773ba3 100644 --- a/unit-test-coverage.yaml +++ b/unit-test-coverage.yaml @@ -1,7 +1,7 @@ packages: cmd/modulectl/scaffold: 100 internal/common/validation: 86 - internal/service/scaffold: 93 + internal/service/scaffold: 92 internal/service/contentprovider: 100 internal/service/filegenerator: 100 internal/service/moduleconfig/generator: 100 From 6d007b6a24a2829afe5d75e121656eeaec328e7c Mon Sep 17 00:00:00 2001 From: Benjamin Lindner Date: Thu, 26 Sep 2024 12:57:52 +0200 Subject: [PATCH 40/40] retrigger jobs