diff --git a/oci/tests/integration/.env.sample b/oci/tests/integration/.env.sample index e50eb0c1..12357f86 100644 --- a/oci/tests/integration/.env.sample +++ b/oci/tests/integration/.env.sample @@ -11,12 +11,14 @@ # export TF_VAR_rand=${RANDOM} ## Azure +# export ARM_SUBSCRIPTION_ID= +# export TF_VAR_azuredevops_org= +# export TF_VAR_azuredevops_pat= # export TF_VAR_azure_location=eastus ## Set the following only when authenticating using Service Principal (suited ## for CI environment). # export ARM_CLIENT_ID= # export ARM_CLIENT_SECRET= -# export ARM_SUBSCRIPTION_ID= # export ARM_TENANT_ID= ## GCP @@ -48,3 +50,7 @@ # export TF_VAR_wi_k8s_sa_name=test-workload-id # export TF_VAR_wi_k8s_sa_ns=default # export TF_VAR_enable_wi=true + +## Test Configuration variables +# export TF_VAR_enable_git=true +# export TF_VAR_enable_oci=true diff --git a/oci/tests/integration/Makefile b/oci/tests/integration/Makefile index 2183bfd6..dfe5954f 100644 --- a/oci/tests/integration/Makefile +++ b/oci/tests/integration/Makefile @@ -1,4 +1,5 @@ GO_TEST_ARGS ?= +GO_TEST_PREFIX ?= PROVIDER_ARG ?= TEST_TIMEOUT ?= 30m GOARCH ?= amd64 @@ -15,7 +16,7 @@ docker-build: app test: docker image inspect $(TEST_IMG) >/dev/null - TEST_IMG=$(TEST_IMG) go test -timeout $(TEST_TIMEOUT) -v ./ $(GO_TEST_ARGS) $(PROVIDER_ARG) --tags=integration + TEST_IMG=$(TEST_IMG) go test -timeout $(TEST_TIMEOUT) -v ./ -run "^$(GO_TEST_PREFIX).*" $(GO_TEST_ARGS) $(PROVIDER_ARG) --tags=integration test-aws: $(MAKE) test PROVIDER_ARG="-provider aws" @@ -23,6 +24,12 @@ test-aws: test-azure: $(MAKE) test PROVIDER_ARG="-provider azure" +test-azure-git: + $(MAKE) test PROVIDER_ARG="-provider azure" GO_TEST_PREFIX="TestGit" + +test-azure-oci: + $(MAKE) test PROVIDER_ARG="-provider azure" GO_TEST_PREFIX="TestOci" + test-gcp: $(MAKE) test PROVIDER_ARG="-provider gcp" diff --git a/oci/tests/integration/README.md b/oci/tests/integration/README.md index 3fc14ce3..92d28c10 100644 --- a/oci/tests/integration/README.md +++ b/oci/tests/integration/README.md @@ -1,7 +1,7 @@ -# OCI integration test +# Integration tests -OCI integration test uses a test application(`testapp/`) to test the -oci package against each of the supported cloud providers. +Integration tests uses a test application(`testapp/`) to test the +oci and git package against each of the supported cloud providers. **NOTE:** Tests in this package aren't run automatically by the `test-*` make target at the root of `fluxcd/pkg` repo. These tests are more complicated than @@ -16,7 +16,7 @@ runs the test app as a batch job which tries to log in and list tags from the test registry repository. A successful job indicates successful test. If the job fails, the test fails. -Logs of a successful job run: +Logs of a successful job run for oci: ```console $ kubectl logs test-job-93tbl-4jp2r 2022/07/28 21:59:06 repo: xxx.dkr.ecr.us-east-2.amazonaws.com/test-repo-flux-test-heroic-ram @@ -25,6 +25,25 @@ $ kubectl logs test-job-93tbl-4jp2r 2022/07/28 21:59:06 tags: [v0.1.4 v0.1.3 v0.1.0 v0.1.2] ``` +Logs of a successful job run for git: +```console +$ kubectl logs test-job-dzful-jrcqw +2024/08/27 22:28:22 Successfully cloned repository +2024/08/27 22:28:22 apiVersion: v1 +kind: ConfigMap +metadata: + name: foobar +2024/08/27 22:28:22 Keys in cache 0 [https://dev.azure.com/xxx/fluxProjpopularosheepdog/_git/fluxRepopopularosheepdog] +2024/08/27 22:28:22 Cache entry expiration 2024-08-28 22:28:21.335223377 +0000 UTC +2024/08/27 22:28:22 Successfully cloned repository +2024/08/27 22:28:22 apiVersion: v1 +kind: ConfigMap +metadata: + name: foobar +2024/08/27 22:28:22 Keys in cache 1 [https://dev.azure.com/xxx/fluxProjpopularosheepdog/_git/fluxRepopopularosheepdog] +2024/08/27 22:28:22 Cache entry expiration 2024-08-28 22:28:21.335223377 +0000 UTC +``` + ## Requirements ### Amazon Web Services @@ -42,6 +61,18 @@ $ kubectl logs test-job-93tbl-4jp2r workloads to access ACR. - Azure CLI, need to be logged in using `az login` as a User (not a Service Principal). +- An Azure DevOps organization [connected to Microsoft + Entra](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/connect-organization-to-azure-ad?view=azure-devops), + personal access token for accessing repositories within the organization. The + scope required for the personal access token is: + - Project and Team - read, write and manage access + - Member Entitlement Management (Read & Write) + - Code - Full + - Please take a look at the [terraform + provider](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/guides/authenticating_using_the_personal_access_token#create-a-personal-access-token) + for more explanation. + - A valid Azure devops configuration is needed even if git is not being + tested. **NOTE:** To use Service Principal (for example in CI environment), set the `ARM-*` variables in `.env`, source it and authenticate Azure CLI with: @@ -246,9 +277,10 @@ Run the test with `make test-*`, setting the test app image with variable $ make test-azure make test PROVIDER_ARG="-provider azure" docker image inspect fluxcd/testapp:test >/dev/null -TEST_IMG=fluxcd/testapp:test go test -timeout 30m -v ./ -verbose -retain -provider azure --tags=integration -2022/07/29 02:06:51 Terraform binary: /usr/bin/terraform -2022/07/29 02:06:51 Init Terraform +TEST_IMG=fluxcd/testapp:test go test -timeout 30m -v ./ -run "^.*" -provider azure --tags=integration +2024/08/26 23:39:13 Terraform binary: /snap/bin/terraform +2024/08/26 23:39:13 Init Terraform +2024/08/26 23:39:15 Applying Terraform ... ``` @@ -258,7 +290,10 @@ the resources don't get deleted, the `make destroy-*` commands can be run for the respective provider. This will run terraform destroy in the respective provider's terraform configuration directory. This can be used to quickly destroy the infrastructure without going through the provision-test-destroy -steps. +steps. There is a known issue with Azure user not getting cleaned up if the +infrastructure is retained and destroy is used for cleanup. The workaround is to +manually delete the user from Azure DevOps Organization +Settings->Users page. ## Workload Identity @@ -273,6 +308,8 @@ export TF_VAR_enable_wi= They have been included in the `.env.sample` and you can simply uncomment it. +The git integration tests require workload identity to be enabled. + ## Debugging the tests For debugging environment provisioning, enable verbose output with `-verbose` diff --git a/oci/tests/integration/aws_test.go b/oci/tests/integration/aws_test.go index 640a514b..48e0ed57 100644 --- a/oci/tests/integration/aws_test.go +++ b/oci/tests/integration/aws_test.go @@ -98,3 +98,18 @@ func getWISAAnnotationsAWS(output map[string]*tfjson.StateOutput) (map[string]st eksRoleArnAnnotation: iamARN, }, nil } + +// When implemented, getGitTestConfigAws would return the git-specific test config for AWS +func getGitTestConfigAWS(outputs map[string]*tfjson.StateOutput) (*gitTestConfig, error) { + return nil, fmt.Errorf("NotImplemented for AWS") +} + +// When implemented, givePermissionsToRepositoryAWS would grant the required permissions to AWS CodeCommit repository +func givePermissionsToRepositoryAWS(ctx context.Context, output map[string]*tfjson.StateOutput) (string, error) { + return "", fmt.Errorf("NotImplemented for AWS") +} + +// When implemented, revokePermissionsToRepositoryAWS would revoke the permissions granted to AWS CodeCommit repository +func revokePermissionsToRepositoryAWS(ctx context.Context, gitPermissionID string, outputs map[string]*tfjson.StateOutput) error { + return fmt.Errorf("NotImplemented for AWS") +} diff --git a/oci/tests/integration/azure_test.go b/oci/tests/integration/azure_test.go index 104ca721..8b920ac6 100644 --- a/oci/tests/integration/azure_test.go +++ b/oci/tests/integration/azure_test.go @@ -22,10 +22,18 @@ package integration import ( "context" "fmt" + "log" + "strings" + "time" - tfjson "github.com/hashicorp/terraform-json" - + "github.com/fluxcd/pkg/git" "github.com/fluxcd/test-infra/tftestenv" + "github.com/google/uuid" + tfjson "github.com/hashicorp/terraform-json" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/graph" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/licensing" + "github.com/microsoft/azure-devops-go-api/azuredevops/v7/memberentitlementmanagement" ) const ( @@ -81,3 +89,147 @@ func getWISAAnnotationsAzure(output map[string]*tfjson.StateOutput) (map[string] azureWIClientIdAnnotation: clientID, }, nil } + +// Give managed identity permissions on the azure devops project using azure-devops-go-api +// https://github.com/microsoft/azure-devops-go-api/blob/dev/azuredevops/v7/memberentitlementmanagement/client.go#L147 +// This can be moved to terraform if/when this PR completes - +// https://github.com/microsoft/terraform-provider-azuredevops/pull/1028 +// Returns a string representing the uuid of the entity that was granted permissions +func givePermissionsToRepositoryAzure(ctx context.Context, outputs map[string]*tfjson.StateOutput) (string, error) { + // Organization, PAT, Project ID and WI ID are availble as terraform output + organization := outputs["azure_devops_organization"].Value.(string) + projectId := outputs["azure_devops_project_id"].Value.(string) + pat := outputs["azure_devops_access_token"].Value.(string) + wiObjectId := outputs["workload_identity_object_id"].Value.(string) + var servicePrincipalID string + + // Create a connection to the organization and create a new client + connection := azuredevops.NewPatConnection(fmt.Sprintf("https://dev.azure.com/%s", organization), pat) + client, err := memberentitlementmanagement.NewClient(ctx, connection) + if err != nil { + return servicePrincipalID, err + } + + uuid, err := uuid.Parse(projectId) + if err != nil { + return servicePrincipalID, err + } + origin := "AAD" + kind := "servicePrincipal" + servicePrincipal := memberentitlementmanagement.ServicePrincipalEntitlement{ + AccessLevel: &licensing.AccessLevel{ + AccountLicenseType: &licensing.AccountLicenseTypeValues.Express, + }, + ProjectEntitlements: &[]memberentitlementmanagement.ProjectEntitlement{ + { + ProjectRef: &memberentitlementmanagement.ProjectRef{ + Id: &uuid, + }, + Group: &memberentitlementmanagement.Group{ + GroupType: &memberentitlementmanagement.GroupTypeValues.ProjectContributor, + }, + }, + }, + ServicePrincipal: &graph.GraphServicePrincipal{ + Origin: &origin, + OriginId: &wiObjectId, + SubjectKind: &kind, + }, + } + + // First request to add new user fails, second request succeeds, add a retry + retryAttempts := 2 + retryDelay := 1 * time.Second // 1 seconds delay + attempts := 0 + for attempts < retryAttempts { + attempts++ + responseValue, err := client.AddServicePrincipalEntitlement(ctx, memberentitlementmanagement.AddServicePrincipalEntitlementArgs{ServicePrincipalEntitlement: &servicePrincipal}) + if err != nil { + return servicePrincipalID, err + } + + if !*responseValue.OperationResult.IsSuccess { + errMsg := getServicePrincipalEntitlementAPIErrorMessage(*responseValue.OperationResult) + if strings.Contains(errMsg, "VS403283: Could not add user") { + log.Println("Retryable error encountered", errMsg) + time.Sleep(retryDelay) + continue + } else { + return servicePrincipalID, fmt.Errorf(errMsg) + } + } + uuid := responseValue.OperationResult.ServicePrincipalId + servicePrincipalID = uuid.String() + break + } + + log.Println("Added service principal entitlement", servicePrincipalID) + + return servicePrincipalID, nil +} + +func getServicePrincipalEntitlementAPIErrorMessage(operationResult memberentitlementmanagement.ServicePrincipalEntitlementOperationResult) string { + errMsg := "Unknown API error" + if operationResult.Errors != nil && len(*operationResult.Errors) > 0 { + var errorMessages []string + for _, err := range *operationResult.Errors { + errorMessages = append(errorMessages, fmt.Sprintf("(%v) %s", *err.Key, *err.Value)) + } + errMsg = strings.Join(errorMessages, "\n") + } + return errMsg +} + +// revokePermissionsToRepositoryAzure deletes the managed identity from users list in the organization using azure-devops-go-api +// https://github.com/microsoft/azure-devops-go-api/blob/dev/azuredevops/v7/memberentitlementmanagement/client.go#L235 +func revokePermissionsToRepositoryAzure(ctx context.Context, servicePrincipalID string, outputs map[string]*tfjson.StateOutput) error { + uuid, err := uuid.Parse(servicePrincipalID) + if err != nil { + return err + } + // Organization, PAT, Project ID and WI ID are availble as terraform output + organization := outputs["azure_devops_organization"].Value.(string) + pat := outputs["azure_devops_access_token"].Value.(string) + + // Create a connection to the organization and create a new client + connection := azuredevops.NewPatConnection(fmt.Sprintf("https://dev.azure.com/%s", organization), pat) + client, err := memberentitlementmanagement.NewClient(ctx, connection) + if err != nil { + return err + } + + err = client.DeleteServicePrincipalEntitlement(ctx, memberentitlementmanagement.DeleteServicePrincipalEntitlementArgs{ServicePrincipalId: &uuid}) + if err != nil { + log.Fatal(err) + } + + return nil +} + +// getGitTestConfigAzure returns the test config used to setup the git repository +func getGitTestConfigAzure(outputs map[string]*tfjson.StateOutput) (*gitTestConfig, error) { + config := &gitTestConfig{ + defaultGitTransport: git.HTTP, + gitUsername: git.DefaultPublicKeyAuthUser, + gitPat: outputs["azure_devops_access_token"].Value.(string), + applicationRepository: outputs["git_repo_url"].Value.(string), + } + + opts, err := getAuthOpts(config.applicationRepository, map[string][]byte{ + "password": []byte(config.gitPat), + "username": []byte(git.DefaultPublicKeyAuthUser), + }) + if err != nil { + return nil, err + } + config.defaultAuthOpts = opts + + parts := strings.Split(config.applicationRepository, "@") + // Check if the URL contains the "@" symbol + if len(parts) > 1 { + // Reconstruct the URL without the username + config.applicationRepositoryWithoutUser = "https://" + parts[1] + } + + return config, nil +} diff --git a/oci/tests/integration/gcp_test.go b/oci/tests/integration/gcp_test.go index a92b5791..708ba775 100644 --- a/oci/tests/integration/gcp_test.go +++ b/oci/tests/integration/gcp_test.go @@ -90,3 +90,18 @@ func getWISAAnnotationsGCP(output map[string]*tfjson.StateOutput) (map[string]st gcpIAMAnnotation: saEmail, }, nil } + +// When implemented, getGitTestConfigGCP would return the git-specific test config for GCP +func getGitTestConfigGCP(outputs map[string]*tfjson.StateOutput) (*gitTestConfig, error) { + return nil, fmt.Errorf("NotImplemented for GCP") +} + +// When implemented, givePermissionsToRepositoryGCP would grant the required permissions to Google cloud source repositories +func givePermissionsToRepositoryGCP(ctx context.Context, output map[string]*tfjson.StateOutput) (string, error) { + return "", fmt.Errorf("NotImplemented for GCP") +} + +// When implemented, revokePermissionsToRepositoryGCP would revoke the permissions granted to Google cloud source repositories +func revokePermissionsToRepositoryGCP(ctx context.Context, gitPermissionID string, outputs map[string]*tfjson.StateOutput) error { + return fmt.Errorf("NotImplemented for AWS") +} diff --git a/oci/tests/integration/git_test.go b/oci/tests/integration/git_test.go new file mode 100644 index 00000000..3ff5bb3e --- /dev/null +++ b/oci/tests/integration/git_test.go @@ -0,0 +1,46 @@ +//go:build integration +// +build integration + +/* +Copyright 2022 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "context" + "fmt" + "testing" +) + +func TestGitCloneUsingProvider(t *testing.T) { + if !enableGit { + t.Skip("Skipping test, enable git in env, supported providers ", supportedGitProviders) + } + + ctx := context.TODO() + tmpDir := t.TempDir() + + setUpGitRepository(ctx, tmpDir) + t.Run("Git oidc credential test", func(t *testing.T) { + args := []string{ + "-category=git", + "-oidc-login=true", + fmt.Sprintf("-provider=%s", *targetProvider), + fmt.Sprintf("-repo=%s", testGitCfg.applicationRepositoryWithoutUser), + } + testjobExecutionWithArgs(t, args) + }) +} diff --git a/oci/tests/integration/go.mod b/oci/tests/integration/go.mod index 3ec4ef63..55de651d 100644 --- a/oci/tests/integration/go.mod +++ b/oci/tests/integration/go.mod @@ -1,6 +1,8 @@ module github.com/fluxcd/pkg/oci/tests/integration -go 1.22.0 +go 1.22.4 + +toolchain go1.22.5 replace ( github.com/fluxcd/pkg/cache => ../../../cache @@ -8,24 +10,32 @@ replace ( ) require ( - github.com/fluxcd/pkg/cache v0.0.1 + github.com/fluxcd/pkg/cache v0.0.3 + github.com/fluxcd/pkg/git v0.19.0 + github.com/fluxcd/pkg/git/gogit v0.19.0 github.com/fluxcd/pkg/oci v0.34.0 github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c + github.com/go-git/go-git/v5 v5.12.0 github.com/google/go-containerregistry v0.19.1 + github.com/google/uuid v1.6.0 github.com/hashicorp/terraform-exec v0.20.0 github.com/hashicorp/terraform-json v0.19.0 - github.com/onsi/gomega v1.33.1 - k8s.io/api v0.30.0 - k8s.io/apimachinery v0.30.0 - sigs.k8s.io/controller-runtime v0.18.1 + github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0 + github.com/onsi/gomega v1.34.1 + k8s.io/api v0.31.0 + k8s.io/apimachinery v0.31.0 + sigs.k8s.io/controller-runtime v0.19.0 ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect @@ -43,20 +53,28 @@ require ( github.com/aws/smithy-go v1.20.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/cli v24.0.9+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/fluxcd/cli-utils v0.36.0-flux.7 // indirect + github.com/fluxcd/cli-utils v0.36.0-flux.9 // indirect + github.com/fluxcd/pkg/auth v0.0.0-00010101000000-000000000000 // indirect + github.com/fluxcd/pkg/ssh v0.13.0 // indirect + github.com/fluxcd/pkg/version v0.4.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-errors/errors v1.5.1 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -69,17 +87,18 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hc-install v0.6.2 // indirect github.com/imdario/mergo v0.3.15 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // 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.4 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -89,45 +108,58 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.19.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.20.0 // 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/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/vbatts/tar-split v0.11.3 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/zclconf/go-cty v1.14.1 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.19.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.5.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.22.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.6.0 // indirect + golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.33.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/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.30.0 // indirect - k8s.io/cli-runtime v0.30.0 // indirect - k8s.io/client-go v0.30.0 // indirect - k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/cli-runtime v0.31.0 // 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-20230726121419-3b25d923346b // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // 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/kustomize/api v0.17.3 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) + +replace github.com/fluxcd/pkg/auth => github.com/dipti-pai/pkg/auth v0.0.0-20240822170700-a2f84e127913 + +replace github.com/fluxcd/pkg/git/gogit => github.com/dipti-pai/pkg/git/gogit v0.0.0-20240822170700-a2f84e127913 + +replace github.com/fluxcd/pkg/git => github.com/dipti-pai/pkg/git v0.0.0-20240822170700-a2f84e127913 diff --git a/oci/tests/integration/go.sum b/oci/tests/integration/go.sum index 8fc2c40d..2c971b7b 100644 --- a/oci/tests/integration/go.sum +++ b/oci/tests/integration/go.sum @@ -1,12 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= +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/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= @@ -15,12 +15,19 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/config v1.27.11 h1:f47rANd2LQEYHda2ddSCKYId18/8BhSRM4BULGmfgNA= @@ -55,8 +62,8 @@ 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/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -76,8 +83,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dipti-pai/pkg/auth v0.0.0-20240822170700-a2f84e127913 h1:uUaYV/QbxgLW1kYYKhSrrJFYp/D94ogYoRtBRM/Trfk= +github.com/dipti-pai/pkg/auth v0.0.0-20240822170700-a2f84e127913/go.mod h1:GyfTIyzUHtsVQG0OsetFI4rA9Vinbt0AdFKKYewWm5E= +github.com/dipti-pai/pkg/git v0.0.0-20240822170700-a2f84e127913 h1:JE4MuxE3P7ctLy9tCies8rsvPcJcAVyhmWTaeb6D4aI= +github.com/dipti-pai/pkg/git v0.0.0-20240822170700-a2f84e127913/go.mod h1:7+ND7LWwCVRuO0ZAb+TPWQF6M3SObY10VIodFToGW+A= +github.com/dipti-pai/pkg/git/gogit v0.0.0-20240822170700-a2f84e127913 h1:quDlLeIOI59IeI0WXFJlSJD8QEiNuYgk2OtHhNxquK0= +github.com/dipti-pai/pkg/git/gogit v0.0.0-20240822170700-a2f84e127913/go.mod h1:enJclTZCS1HLaXeC3zTu16axNLamghes0p48Km/owvY= github.com/docker/cli v24.0.9+incompatible h1:OxbimnP/z+qVjDLpq9wbeFU3Nc30XhSe+LkwYQisD50= github.com/docker/cli v24.0.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -86,6 +97,8 @@ github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKs github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= +github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -98,22 +111,36 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/fluxcd/cli-utils v0.36.0-flux.7 h1:81zEo/LNmIRWMgtsZy/8L13TMUZHmmJib4gHRvKwVE8= -github.com/fluxcd/cli-utils v0.36.0-flux.7/go.mod h1:TcfLhvBjtQnqxYMsHQUAEB2c5WJRVuibtas2Izz5ZTs= +github.com/fluxcd/cli-utils v0.36.0-flux.9 h1:RITKdwIAqT3EFKXl7B91mj6usVjxcy7W8PJZlxqUa84= +github.com/fluxcd/cli-utils v0.36.0-flux.9/go.mod h1:q6lXQpbAlrZmTB4Qe5oAENkv0y2kwMWcqTMDHrRo2Is= +github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg= +github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo= +github.com/fluxcd/pkg/gittestserver v0.12.0 h1:QGbIVyje9U6urSAeDw3diKb/5wdA+Cnw1YJN+3Zflaw= +github.com/fluxcd/pkg/gittestserver v0.12.0/go.mod h1:Eh82e+kzKdhpafnUwR5oCBmxqAqhF5QuCn290AFntPM= +github.com/fluxcd/pkg/ssh v0.13.0 h1:lPU1Gst8XIz7AU2dhdqVFaaOWd54/O1LZu62vH4JB/s= +github.com/fluxcd/pkg/ssh v0.13.0/go.mod h1:J9eyirMd4s++tWG4euRRhmcthKX203GPHpzFpH++TP8= +github.com/fluxcd/pkg/version v0.4.0 h1:3F6oeIZ+ug/f7pALIBhcUhfURel37EPPOn7nsGfsnOg= +github.com/fluxcd/pkg/version v0.4.0/go.mod h1:izVsSDxac81qWRmpOL9qcxZYx+zAN1ajoP5SidGP6PA= github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c h1:Cz+NgW2Y0rNODbwanioXO79dUgm9mzGBfQyp5COvNz4= github.com/fluxcd/test-infra/tftestenv v0.0.0-20240110132047-17651823b08c/go.mod h1:liFlLEXgambGVdWSJ4JzbIHf1Vjpp1HwUyPazPIVZug= 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/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= 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-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +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/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/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -123,9 +150,10 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= 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/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 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/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -162,10 +190,11 @@ github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDIt 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-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= 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/uuid v1.1.1/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/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -204,8 +233,9 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4 github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 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.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -219,12 +249,14 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0 h1:mmJCWLe63QvybxhW1iBmQWEaCKdc4SKgALfTNZ+OphU= +github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0/go.mod h1:mDunUZ1IUJdJIRHvFb+LPBUtxe3AYB5MI6BMXNg8194= 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/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= +github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= 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= @@ -238,10 +270,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= -github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= 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.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= @@ -257,29 +289,30 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +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.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +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/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 v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +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/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -287,7 +320,9 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS 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.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.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -297,6 +332,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +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/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= @@ -318,13 +355,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/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.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +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-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +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= @@ -332,8 +370,8 @@ 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.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -343,15 +381,16 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +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.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -359,13 +398,16 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ 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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +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-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-20191026070338-33540a1f6037/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-20210124154548-22da62e12c0c/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -376,26 +418,27 @@ 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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.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-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.0.0-20220526004731-065cf7ba2467/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.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +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.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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -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/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.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.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= @@ -406,8 +449,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY 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.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= @@ -430,9 +473,10 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.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.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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= @@ -441,6 +485,7 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/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= @@ -451,34 +496,34 @@ gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= 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.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= -k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= -k8s.io/apiextensions-apiserver v0.30.0 h1:jcZFKMqnICJfRxTgnC4E+Hpcq8UEhT8B2lhBcQ+6uAs= -k8s.io/apiextensions-apiserver v0.30.0/go.mod h1:N9ogQFGcrbWqAY9p2mUAL5mGxsLqwgtUce127VtRX5Y= -k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= -k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= -k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= -k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= -k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= -k8s.io/component-base v0.30.0 h1:cj6bp38g0ainlfYtaOQuRELh5KSYjhKxM+io7AUIk4o= -k8s.io/component-base v0.30.0/go.mod h1:V9x/0ePFNaKeKYA3bOvIbrNoluTSG+fSJKjLdjOoeXQ= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +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.31.0 h1:V2Q1gj1u3/WfhD475HBQrIYsoryg/LrhhK4RwpN+DhA= +k8s.io/cli-runtime v0.31.0/go.mod h1:vg3H94wsubuvWfSmStDbekvbla5vFGC+zLWqcf+bGDw= +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/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= +k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= +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/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= -k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.18.1 h1:RpWbigmuiylbxOCLy0tGnq1cU1qWPwNIQzoJk+QeJx4= -sigs.k8s.io/controller-runtime v0.18.1/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +k8s.io/kubectl v0.31.0 h1:kANwAAPVY02r4U4jARP/C+Q1sssCcN/1p9Nk+7BQKVg= +k8s.io/kubectl v0.31.0/go.mod h1:pB47hhFypGsaHAPjlwrNbvhXgmuAr01ZBvAIIUaI8d4= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +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= -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/kustomize/api v0.17.3 h1:6GCuHSsxq7fN5yhF2XrC+AAr8gxQwhexgHflOAD/JJU= +sigs.k8s.io/kustomize/api v0.17.3/go.mod h1:TuDH4mdx7jTfK61SQ/j1QZM/QWR+5rmEiNjvYlhzFhc= +sigs.k8s.io/kustomize/kyaml v0.17.2 h1:+AzvoJUY0kq4QAhH/ydPHHMRLijtUKiyVyh7fOSshr0= +sigs.k8s.io/kustomize/kyaml v0.17.2/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= 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= diff --git a/oci/tests/integration/repo_list_test.go b/oci/tests/integration/job_test.go similarity index 64% rename from oci/tests/integration/repo_list_test.go rename to oci/tests/integration/job_test.go index 459cf566..dbb76b06 100644 --- a/oci/tests/integration/repo_list_test.go +++ b/oci/tests/integration/job_test.go @@ -21,8 +21,6 @@ package integration import ( "context" - "fmt" - "strings" "testing" . "github.com/onsi/gomega" @@ -32,51 +30,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func TestImageRepositoryListTags(t *testing.T) { - for name, repo := range testRepos { - t.Run(name, func(t *testing.T) { - args := []string{fmt.Sprintf("-repo=%s", repo)} - testImageRepositoryListTags(t, args) - }) - } -} - -func TestRepositoryRootLoginListTags(t *testing.T) { - for name, repo := range testRepos { - t.Run(name, func(t *testing.T) { - parts := strings.SplitN(repo, "/", 2) - args := []string{ - fmt.Sprintf("-registry=%s", parts[0]), - fmt.Sprintf("-repo=%s", parts[1]), - } - testImageRepositoryListTags(t, args) - }) - } -} - -func TestOIDCLoginListTags(t *testing.T) { - for name, repo := range testRepos { - t.Run(name, func(t *testing.T) { - // Registry only. - parts := strings.SplitN(repo, "/", 2) - args := []string{ - "-oidc-login=true", - fmt.Sprintf("-registry=%s", parts[0]), - fmt.Sprintf("-repo=%s", parts[1]), - } - testImageRepositoryListTags(t, args) - - // Registry + repo. - args = []string{ - "-oidc-login=true", - fmt.Sprintf("-repo=%s", repo), - } - testImageRepositoryListTags(t, args) - }) - } -} - -func testImageRepositoryListTags(t *testing.T, args []string) { +func testjobExecutionWithArgs(t *testing.T, args []string) { + t.Helper() g := NewWithT(t) ctx := context.TODO() @@ -107,10 +62,12 @@ func testImageRepositoryListTags(t *testing.T, args []string) { key := client.ObjectKeyFromObject(job) g.Expect(testEnv.Client.Create(ctx, job)).To(Succeed()) + defer func() { background := metav1.DeletePropagationBackground g.Expect(testEnv.Client.Delete(ctx, job, &client.DeleteOptions{PropagationPolicy: &background})).To(Succeed()) }() + g.Eventually(func() bool { if err := testEnv.Client.Get(ctx, key, job); err != nil { return false diff --git a/oci/tests/integration/oci_test.go b/oci/tests/integration/oci_test.go new file mode 100644 index 00000000..49c59840 --- /dev/null +++ b/oci/tests/integration/oci_test.go @@ -0,0 +1,100 @@ +//go:build integration +// +build integration + +/* +Copyright 2022 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "fmt" + "strings" + "testing" +) + +func TestOciImageRepositoryListTags(t *testing.T) { + if !enableOci { + t.Skip("Skipping test as oci is not enabled in env") + } + + if len(testRepos) == 0 { + t.Fatalf("expected testRepos to be set") + } + + for name, repo := range testRepos { + t.Run(name, func(t *testing.T) { + args := []string{ + "-category=oci", + fmt.Sprintf("-repo=%s", repo), + } + testjobExecutionWithArgs(t, args) + }) + } +} + +func TestOciRepositoryRootLoginListTags(t *testing.T) { + if !enableOci { + t.Skip("Skipping test as oci is not enabled in env") + } + + if len(testRepos) == 0 { + t.Fatalf("expected testRepos to be set") + } + + for name, repo := range testRepos { + t.Run(name, func(t *testing.T) { + parts := strings.SplitN(repo, "/", 2) + args := []string{ + "-category=oci", + fmt.Sprintf("-registry=%s", parts[0]), + fmt.Sprintf("-repo=%s", parts[1]), + } + testjobExecutionWithArgs(t, args) + }) + } +} + +func TestOciOIDCLoginListTags(t *testing.T) { + if !enableOci { + t.Skip("Skipping test as oci is not enabled in env") + } + + if len(testRepos) == 0 { + t.Fatalf("expected testRepos to be set") + } + + for name, repo := range testRepos { + t.Run(name, func(t *testing.T) { + // Registry only. + parts := strings.SplitN(repo, "/", 2) + args := []string{ + "-category=oci", + "-oidc-login=true", + fmt.Sprintf("-registry=%s", parts[0]), + fmt.Sprintf("-repo=%s", parts[1]), + } + testjobExecutionWithArgs(t, args) + + // Registry + repo. + args = []string{ + "-category=oci", + "-oidc-login=true", + fmt.Sprintf("-repo=%s", repo), + } + testjobExecutionWithArgs(t, args) + }) + } +} diff --git a/oci/tests/integration/suite_test.go b/oci/tests/integration/suite_test.go index 2ddc566e..44d020f4 100644 --- a/oci/tests/integration/suite_test.go +++ b/oci/tests/integration/suite_test.go @@ -37,6 +37,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "github.com/fluxcd/pkg/git" "github.com/fluxcd/test-infra/tftestenv" ) @@ -66,11 +67,20 @@ const ( ) var ( + // supportedOciProviders are the providers supported by the test. + supportedOciProviders = []string{"aws", "azure", "gcp"} + // supportedProviders are the providers supported by the test. - supportedProviders = []string{"aws", "azure", "gcp"} + supportedGitProviders = []string{"azure"} // targetProvider is the name of the kubernetes provider to test against. - targetProvider = flag.String("provider", "", fmt.Sprintf("name of the provider %v", supportedProviders)) + targetProvider = flag.String("provider", "", fmt.Sprintf("name of the provider %v for oci, %v for git", supportedOciProviders, supportedGitProviders)) + + // enableOci is set to true when oci is enabled in env and a supported provider is specified. + enableOci bool + + // enableGit is set to true when oci is enabled in env and a supported provider is specified. + enableGit bool // retain flag to prevent destroy and retaining the created infrastructure. retain = flag.Bool("retain", false, "retain the infrastructure for debugging purposes") @@ -106,8 +116,14 @@ var ( // identity. It is set from the terraform variable (`TF_VAR_k8s_serviceaccount_name`) wiServiceAccount string - // enableWI is set to true when the TF_vAR_enable_wi is set to "true", so the tests run for Workload Identtty + // enableWI is set to true when the TF_VAR_enable_wi is set to "true", so the tests run for Workload Identtty enableWI bool + + // testGitCfg is a struct containing different variables needed for running git tests. + testGitCfg *gitTestConfig + + // gitPermissionID is a string that represents the entity that was granted permissions on the git repository + gitPermissionID string ) // registryLoginFunc is used to perform registry login against a provider based @@ -126,6 +142,26 @@ type pushTestImages func(ctx context.Context, localImgs map[string]string, outpu // service account when workload identity is used on the cluster. type getWISAAnnotations func(output map[string]*tfjson.StateOutput) (map[string]string, error) +// givePermissionsToRepository calls provider specific API to add additional permissions to the git repository/project +type givePermissionsToRepository func(ctx context.Context, output map[string]*tfjson.StateOutput) (string, error) + +// revokePermissionsToRepository calls provider specific API to revoke permissions to the git repository/project +type revokePermissionsToRepository func(ctx context.Context, gitPermissionID string, output map[string]*tfjson.StateOutput) error + +// getGitTestConfig gets the configuration for the tests +type getGitTestConfig func(output map[string]*tfjson.StateOutput) (*gitTestConfig, error) + +// gitTestConfig hold different variable that will be needed by the different test functions. +type gitTestConfig struct { + // authentication info for git repositories + gitPat string + gitUsername string + defaultGitTransport git.TransportType + defaultAuthOpts *git.AuthOptions + applicationRepository string + applicationRepositoryWithoutUser string +} + // ProviderConfig is the test configuration of a supported cloud provider to run // the tests against. type ProviderConfig struct { @@ -141,6 +177,12 @@ type ProviderConfig struct { // getWISAAnnotations is used to return the provider specific annotations // for the service account when using workload identity. getWISAAnnotations getWISAAnnotations + // givePermissionsToRepository is used to give the identity access to the Git repository + givePermissionsToRepository givePermissionsToRepository + // revokePermissionsToRepository is used to revoke the identity access to the Git repository + revokePermissionsToRepository revokePermissionsToRepository + // getGitTestConfig is used to return provider specific test configuration + getGitTestConfig getGitTestConfig } var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz1234567890") @@ -159,16 +201,20 @@ func TestMain(m *testing.M) { // Validate the provider. if *targetProvider == "" { - log.Fatalf("-provider flag must be set to one of %v", supportedProviders) + log.Fatalf("-provider flag must be set to one of %v for git or %v for oci", supportedGitProviders, supportedOciProviders) } - var supported bool - for _, p := range supportedProviders { - if p == *targetProvider { - supported = true - } + + if os.Getenv("TF_VAR_enable_git") == "true" && supportedProvider(*targetProvider, supportedGitProviders) { + enableGit = true } - if !supported { - log.Fatalf("Unsupported provider %q, must be one of %v", *targetProvider, supportedProviders) + + if os.Getenv("TF_VAR_enable_oci") == "true" && supportedProvider(*targetProvider, supportedOciProviders) { + enableOci = true + } + + enableWI = os.Getenv("TF_VAR_enable_wi") == "true" + if enableGit && !enableWI { + log.Fatalf("Workload identity must be enabled to run git tests") } providerCfg := getProviderConfig(*targetProvider) @@ -249,12 +295,81 @@ func TestMain(m *testing.M) { panic(fmt.Sprintf("Failed to get the terraform state output: %v", err)) } - testRepos, err = providerCfg.registryLogin(ctx, output) + // Cleanup infra that depends on terraform output before exit + defer func() { + if !*retain { + if gitPermissionID != "" { + err := providerCfg.revokePermissionsToRepository(ctx, gitPermissionID, output) + if err != nil { + log.Printf("Failed to revoke permissions to git repository: %v", gitPermissionID) + exitCode = 1 + } + } + } + }() + + pushAppImage(ctx, providerCfg, output, localImgs) + configureAdditionalInfra(ctx, providerCfg, output) + + exitCode = m.Run() +} + +func supportedProvider(targetProvider string, supportedProviders []string) bool { + for _, p := range supportedProviders { + if p == targetProvider { + return true + } + } + return false +} + +// getProviderConfig returns the test configuration of supported providers. +func getProviderConfig(provider string) *ProviderConfig { + switch provider { + case "aws": + return &ProviderConfig{ + terraformPath: terraformPathAWS, + registryLogin: registryLoginECR, + pushAppTestImages: pushAppTestImagesECR, + createKubeconfig: createKubeconfigEKS, + getWISAAnnotations: getWISAAnnotationsAWS, + givePermissionsToRepository: givePermissionsToRepositoryAWS, + revokePermissionsToRepository: revokePermissionsToRepositoryAWS, + getGitTestConfig: getGitTestConfigAWS, + } + case "azure": + providerCfg := &ProviderConfig{ + terraformPath: terraformPathAzure, + registryLogin: registryLoginACR, + pushAppTestImages: pushAppTestImagesACR, + createKubeconfig: createKubeConfigAKS, + getWISAAnnotations: getWISAAnnotationsAzure, + givePermissionsToRepository: givePermissionsToRepositoryAzure, + revokePermissionsToRepository: revokePermissionsToRepositoryAzure, + getGitTestConfig: getGitTestConfigAzure, + } + return providerCfg + case "gcp": + return &ProviderConfig{ + terraformPath: terraformPathGCP, + registryLogin: registryLoginGCR, + pushAppTestImages: pushAppTestImagesGCR, + createKubeconfig: createKubeconfigGKE, + getWISAAnnotations: getWISAAnnotationsGCP, + givePermissionsToRepository: givePermissionsToRepositoryGCP, + revokePermissionsToRepository: revokePermissionsToRepositoryGCP, + getGitTestConfig: getGitTestConfigGCP, + } + } + return nil +} + +func pushAppImage(ctx context.Context, providerCfg *ProviderConfig, tfOutput map[string]*tfjson.StateOutput, localImgs map[string]string) { + _, err := providerCfg.registryLogin(ctx, tfOutput) if err != nil { panic(fmt.Sprintf("Failed to log into registry: %v", err)) } - - pushedImages, err := providerCfg.pushAppTestImages(ctx, localImgs, output) + pushedImages, err := providerCfg.pushAppTestImages(ctx, localImgs, tfOutput) if err != nil { panic(fmt.Sprintf("Failed to push test images: %v", err)) } @@ -268,64 +383,62 @@ func TestMain(m *testing.M) { } else { testAppImage = appImg } +} - // Create and push test images. - if err := tftestenv.CreateAndPushImages(testRepos, testImageTags); err != nil { - panic(fmt.Sprintf("Failed to create and push images: %v", err)) +func configureAdditionalInfra(ctx context.Context, providerCfg *ProviderConfig, tfOutput map[string]*tfjson.StateOutput) { + if enableOci { + log.Println("OCI is enabled, push oci test images") + pushOciTestImages(ctx, providerCfg, tfOutput) + } + + if enableGit { + var err error + log.Println("Git is enabled, get test config") + testGitCfg, err = providerCfg.getGitTestConfig(tfOutput) + + if err != nil { + panic(fmt.Sprintf("Failed to get Git test config : %v", err)) + } + + // Call provider specific API to configure permisions for the git repository + log.Println("Giving permissions to workload identity to access repository") + gitPermissionID, err = providerCfg.givePermissionsToRepository(ctx, tfOutput) + if err != nil { + panic(fmt.Sprintf("Failed to grant permissions to repository: %v", err)) + } } - enableWI = os.Getenv("TF_VAR_enable_wi") == "true" if enableWI { - log.Println("Running tests with workload identity enabled") - annotations, err := providerCfg.getWISAAnnotations(output) + log.Println("Workload identity is enabled, initializing service account with annotations") + annotations, err := providerCfg.getWISAAnnotations(tfOutput) if err != nil { panic(fmt.Sprintf("Failed to get service account func for workload identity: %v", err)) } - if err := creatWorkloadIDServiceAccount(ctx, annotations); err != nil { + if err := createWorkloadIDServiceAccount(ctx, annotations); err != nil { panic(err) } } - - exitCode = m.Run() } -// getProviderConfig returns the test configuration of supported providers. -func getProviderConfig(provider string) *ProviderConfig { - switch provider { - case "aws": - return &ProviderConfig{ - terraformPath: terraformPathAWS, - registryLogin: registryLoginECR, - pushAppTestImages: pushAppTestImagesECR, - createKubeconfig: createKubeconfigEKS, - getWISAAnnotations: getWISAAnnotationsAWS, - } - case "azure": - return &ProviderConfig{ - terraformPath: terraformPathAzure, - registryLogin: registryLoginACR, - pushAppTestImages: pushAppTestImagesACR, - createKubeconfig: createKubeConfigAKS, - getWISAAnnotations: getWISAAnnotationsAzure, - } - case "gcp": - return &ProviderConfig{ - terraformPath: terraformPathGCP, - registryLogin: registryLoginGCR, - pushAppTestImages: pushAppTestImagesGCR, - createKubeconfig: createKubeconfigGKE, - getWISAAnnotations: getWISAAnnotationsGCP, - } +func pushOciTestImages(ctx context.Context, providerCfg *ProviderConfig, tfOutput map[string]*tfjson.StateOutput) { + var err error + testRepos, err = providerCfg.registryLogin(ctx, tfOutput) + if err != nil { + panic(fmt.Sprintf("Failed to log into registry: %v", err)) + } + + // Create and push test images. + if err := tftestenv.CreateAndPushImages(testRepos, testImageTags); err != nil { + panic(fmt.Sprintf("Failed to create and push images: %v", err)) } - return nil } // creatWorkloadIDServiceAccount creates the service account (name and namespace specified in the terraform // variables) with the annotations passed into the function. // // TODO: move creation of serviceaccount to terraform -func creatWorkloadIDServiceAccount(ctx context.Context, annotations map[string]string) error { +func createWorkloadIDServiceAccount(ctx context.Context, annotations map[string]string) error { wiServiceAccount = os.Getenv(envVarWISAName) wiSANamespace := os.Getenv(envVarWISANamespace) if wiServiceAccount == "" || wiSANamespace == "" { diff --git a/oci/tests/integration/terraform/azure/main.tf b/oci/tests/integration/terraform/azure/main.tf index fba04c6d..ee208b5a 100644 --- a/oci/tests/integration/terraform/azure/main.tf +++ b/oci/tests/integration/terraform/azure/main.tf @@ -9,7 +9,9 @@ resource "random_pet" "suffix" { } locals { - name = "fluxTest${random_pet.suffix.id}" + name = "fluxTest${random_pet.suffix.id}" + project_name = "fluxProj${random_pet.suffix.id}" + repo_name = "fluxRepo${random_pet.suffix.id}" } module "aks" { @@ -55,3 +57,19 @@ resource "azurerm_federated_identity_credential" "federated-identity2" { depends_on = [module.aks] } + +provider "azuredevops" { + org_service_url = "https://dev.azure.com/${var.azuredevops_org}" + personal_access_token = var.azuredevops_pat +} + +module "devops" { + count = var.enable_git ? 1 : 0 + source = "git::https://github.com/fluxcd/test-infra.git//tf-modules/azure/devops" + providers = { + azuredevops = azuredevops + } + + project_name = local.project_name + repository_name = local.repo_name +} diff --git a/oci/tests/integration/terraform/azure/outputs.tf b/oci/tests/integration/terraform/azure/outputs.tf index 02822208..80241036 100644 --- a/oci/tests/integration/terraform/azure/outputs.tf +++ b/oci/tests/integration/terraform/azure/outputs.tf @@ -14,3 +14,25 @@ output "acr_registry_id" { output "workload_identity_client_id" { value = var.enable_wi ? azurerm_user_assigned_identity.wi-id[0].client_id : "" } + +output "workload_identity_object_id" { + value = var.enable_wi ? azurerm_user_assigned_identity.wi-id[0].principal_id : "" +} + +output "azure_devops_organization" { + value = var.azuredevops_org +} + +output "azure_devops_access_token" { + sensitive = true + value = var.azuredevops_pat +} + +output "git_repo_url" { + value = var.enable_git ? module.devops[0].repo_url : "" +} + +output "azure_devops_project_id" { + value = var.enable_git ? module.devops[0].project_id : "" +} + diff --git a/oci/tests/integration/terraform/azure/variables.tf b/oci/tests/integration/terraform/azure/variables.tf index e2a1f205..369be926 100644 --- a/oci/tests/integration/terraform/azure/variables.tf +++ b/oci/tests/integration/terraform/azure/variables.tf @@ -25,3 +25,21 @@ variable "enable_wi" { default = false description = "Enable workload identity on cluster and create federated identity" } + +variable "enable_git" { + type = bool + default = false + description = "Enable git repository creation" +} + +variable "azuredevops_org" { + type = string + description = "Azure Devops organization to create project and git repository" + default = "" +} + +variable "azuredevops_pat" { + type = string + description = "Personal access token to create project and repository in azure devops" + default = "" +} diff --git a/oci/tests/integration/terraform/azure/version.tf b/oci/tests/integration/terraform/azure/version.tf new file mode 100644 index 00000000..c0d18ac7 --- /dev/null +++ b/oci/tests/integration/terraform/azure/version.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + azuredevops = { + source = "microsoft/azuredevops" + } + } +} \ No newline at end of file diff --git a/oci/tests/integration/testapp/main.go b/oci/tests/integration/testapp/main.go index 4ca6eb9e..44993177 100644 --- a/oci/tests/integration/testapp/main.go +++ b/oci/tests/integration/testapp/main.go @@ -21,6 +21,10 @@ import ( "flag" "fmt" "log" + "net/url" + "os" + "path/filepath" + "slices" "strings" "time" @@ -31,6 +35,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/fluxcd/pkg/cache" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" + "github.com/fluxcd/pkg/git/repository" "github.com/fluxcd/pkg/oci/auth/login" ) @@ -41,13 +48,27 @@ import ( // is provided separately, e.g. registry: foo.azurecr.io, repo: bar. var ( registry = flag.String("registry", "", "registry of the repository") - repo = flag.String("repo", "", "repository to list") + repo = flag.String("repo", "", "git/oci repository to list") oidcLogin = flag.Bool("oidc-login", false, "login with OIDCLogin function") + category = flag.String("category", "", "Test category to run - oci/git") + provider = flag.String("provider", "", "Supported git oidc provider - azure") ) func main() { flag.Parse() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + if *category == "oci" { + checkOci(ctx) + } else if *category == "git" { + checkGit(ctx) + } else { + panic("unsupported category") + } +} + +func checkOci(ctx context.Context) { cache, err := cache.New(5, cache.StoreObjectKeyFunc, cache.WithCleanupInterval[cache.StoreObject[authn.Authenticator]](1*time.Second)) if err != nil { @@ -59,8 +80,6 @@ func main() { AzureAutoLogin: true, Cache: cache, } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() if *repo == "" { panic("must provide -repo value") @@ -106,3 +125,78 @@ func main() { } log.Println("tags:", tags) } + +func checkGit(ctx context.Context) { + u, err := url.Parse(*repo) + if err != nil { + panic(err) + } + + cache, err := cache.New(5, cache.StoreObjectKeyFunc, + cache.WithCleanupInterval[cache.StoreObject[git.Credentials]](10*time.Second)) + if err != nil { + panic(err) + } + + // Clone twice, first time a new token is fetched, subsequently the cached token is used + for i := 0; i < 2; i++ { + var authData map[string][]byte + authOpts, err := git.NewAuthOptions(*u, authData) + if err != nil { + panic(err) + } + authOpts.Cache = cache + authOpts.ProviderOpts = &git.ProviderOptions{ + Name: *provider, + } + cloneDir, err := os.MkdirTemp("", fmt.Sprint("test-clone-", i)) + if err != nil { + panic(err) + } + defer os.RemoveAll(cloneDir) + c, err := gogit.NewClient(cloneDir, authOpts, gogit.WithSingleBranch(false), gogit.WithDiskStorage()) + if err != nil { + panic(err) + } + + _, err = c.Clone(ctx, *repo, repository.CloneConfig{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: "main", + }, + }) + if err != nil { + panic(err) + } + + log.Println("Successfully cloned repository ") + // Check file from clone. + fPath := filepath.Join(cloneDir, "configmap.yaml") + if _, err := os.Stat(fPath); os.IsNotExist(err) { + panic("expected artifact configmap.yaml to exist in clone dir") + } + + // read the whole file at once + contents, err := os.ReadFile(fPath) + if err != nil { + panic(err) + } + log.Println(string(contents)) + keys, err := cache.ListKeys() + if err != nil { + panic(err) + } + log.Println("Keys in cache ", i, keys) + if !slices.Contains(keys, *repo) { + panic("expected cloned repo url to be present in cache") + } + val, exists, err := cache.GetByKey(*repo) + if err != nil || !exists { + panic("expected cloned repo url key to be present in cache") + } + time, err := cache.GetExpiration(val) + if err != nil { + panic("error getting expiration from cache") + } + log.Println("Cache entry expiration ", time) + } +} diff --git a/oci/tests/integration/util_test.go b/oci/tests/integration/util_test.go new file mode 100644 index 00000000..67673e26 --- /dev/null +++ b/oci/tests/integration/util_test.go @@ -0,0 +1,123 @@ +//go:build integration +// +build integration + +/* +Copyright 2024 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "context" + "errors" + "fmt" + "io" + "net/url" + "strings" + "time" + + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" + "github.com/fluxcd/pkg/git/repository" + "github.com/go-git/go-git/v5/plumbing" +) + +const ( + // default branch to be used when cloning git repositories + defaultBranch = "main" +) + +// Clones the git repository specified in the test config and commits a config +// map yaml into the repository +func setUpGitRepository(ctx context.Context, tmpDir string) { + c, err := getRepository(ctx, tmpDir, testGitCfg.applicationRepository, defaultBranch, testGitCfg.defaultAuthOpts) + + if err != nil { + panic(err) + } + + manifest := `apiVersion: v1 +kind: ConfigMap +metadata: + name: foobar` + branchName := defaultBranch + + files := make(map[string]io.Reader) + files["configmap.yaml"] = strings.NewReader(manifest) + err = commitAndPushAll(ctx, c, files, branchName) + + if err != nil { + panic(err) + } +} + +// Uses git package to get auth options +func getAuthOpts(repoURL string, authData map[string][]byte) (*git.AuthOptions, error) { + u, err := url.Parse(repoURL) + if err != nil { + return nil, err + } + + return git.NewAuthOptions(*u, authData) +} + +// getRepository clones the specified branch of the git repository +func getRepository(ctx context.Context, dir, repoURL, branchName string, authOpts *git.AuthOptions) (*gogit.Client, error) { + c, err := gogit.NewClient(dir, authOpts, gogit.WithSingleBranch(false), gogit.WithDiskStorage()) + if err != nil { + return nil, err + } + + _, err = c.Clone(ctx, repoURL, repository.CloneConfig{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: branchName, + }, + }) + if err != nil { + return nil, err + } + + return c, nil +} + +// commitAndPushAll creates a commit and pushes the changes using gogit client +func commitAndPushAll(ctx context.Context, client *gogit.Client, files map[string]io.Reader, branchName string) error { + err := client.SwitchBranch(ctx, branchName) + if err != nil && !errors.Is(err, plumbing.ErrReferenceNotFound) { + return err + } + + _, err = client.Commit(git.Commit{ + Author: git.Signature{ + Name: git.DefaultPublicKeyAuthUser, + Email: "test@example.com", + When: time.Now(), + }, + }, repository.WithFiles(files)) + if err != nil { + if errors.Is(err, git.ErrNoStagedFiles) { + return nil + } + + return err + } + + err = client.Push(ctx, repository.PushConfig{}) + if err != nil { + return fmt.Errorf("unable to push: %s", err) + } + + return nil +}