From 0694a9582fa52191bd591907b2d9cafd1b7f3298 Mon Sep 17 00:00:00 2001 From: Adrien Fillon Date: Mon, 12 Sep 2022 10:22:23 +0200 Subject: [PATCH] Support logging in directly to the provider when pushing OCI artifacts I've noticed during CI, that the current command already expected a configured Docker client to push artifacts to authenticated registries. Some users might not want to have the Docker client in their process (like a CI job) or build an handcrafted config.json file. This would allow this kind of behavior: ``` flux push artifact oci://my-registry.dev/foo:v1 \ --source xxx \ --revision xxx \ --path . \ --creds $TOKEN # Authenticate via "Bearer $TOKEN" Authorization header ``` Or via Autologin: ``` flux push artifact oci://012345678901.dkr.ecr.us-east-1.amazonaws.com/foo:v1 \ --source xxx \ --revision xxx \ --path . \ --provider aws ``` This has been implemented for: * flux push artifact * flux list artifact * flux tag artifact * flux pull artifact This will require another PR in https://github.com/fluxcd/pkg/pull/352 Signed-off-by: Adrien Fillon --- cmd/flux/list_artifact.go | 38 ++++++++++++++++-- cmd/flux/pull_artifact.go | 40 +++++++++++++++++-- cmd/flux/push_artifact.go | 57 +++++++++++++++++++++++++-- cmd/flux/tag_artifact.go | 40 +++++++++++++++++-- go.mod | 11 +++++- go.sum | 25 +++++++++++- internal/flags/source_oci_provider.go | 17 ++++++++ 7 files changed, 210 insertions(+), 18 deletions(-) diff --git a/cmd/flux/list_artifact.go b/cmd/flux/list_artifact.go index ca736997..fc72c32b 100644 --- a/cmd/flux/list_artifact.go +++ b/cmd/flux/list_artifact.go @@ -20,6 +20,8 @@ import ( "context" "fmt" + "github.com/fluxcd/flux2/internal/flags" + sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" "github.com/spf13/cobra" oci "github.com/fluxcd/pkg/oci/client" @@ -30,15 +32,23 @@ import ( type listArtifactFlags struct { semverFilter string regexFilter string + creds string + provider flags.SourceOCIProvider } -var listArtifactArgs listArtifactFlags +var listArtifactArgs = newListArtifactFlags() + +func newListArtifactFlags() listArtifactFlags { + return listArtifactFlags{ + provider: flags.SourceOCIProvider(sourcev1.GenericOCIProvider), + } +} var listArtifactsCmd = &cobra.Command{ Use: "artifacts", Short: "list artifacts", Long: `The list command fetches the tags and their metadata from a remote OCI repository. -The command uses the credentials from '~/.docker/config.json'.`, +The command can read the credentials from '~/.docker/config.json' but they can also be passed with --creds. It can also login to a supported provider with the --provider flag.`, Example: ` # List the artifacts stored in an OCI repository flux list artifact oci://ghcr.io/org/config/app `, @@ -48,6 +58,8 @@ The command uses the credentials from '~/.docker/config.json'.`, func init() { listArtifactsCmd.Flags().StringVar(&listArtifactArgs.semverFilter, "filter-semver", "", "filter tags returned from the oci repository using semver") listArtifactsCmd.Flags().StringVar(&listArtifactArgs.regexFilter, "filter-regex", "", "filter tags returned from the oci repository using regex") + listArtifactsCmd.Flags().StringVar(&listArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format [:] if --provider is generic") + listArtifactsCmd.Flags().Var(&listArtifactArgs.provider, "provider", listArtifactArgs.provider.Description()) listCmd.AddCommand(listArtifactsCmd) } @@ -61,12 +73,32 @@ func listArtifactsCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - ociClient := oci.NewLocalClient() url, err := oci.ParseArtifactURL(ociURL) if err != nil { return err } + ociClient := oci.NewLocalClient() + + if listArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && listArtifactArgs.creds != "" { + logger.Actionf("logging in to registry with credentials") + if err := ociClient.LoginWithCredentials(listArtifactArgs.creds); err != nil { + return fmt.Errorf("could not login with credentials: %w", err) + } + } + + if listArtifactArgs.provider.String() != sourcev1.GenericOCIProvider { + logger.Actionf("logging in to registry with provider credentials") + ociProvider, err := listArtifactArgs.provider.ToOCIProvider() + if err != nil { + return fmt.Errorf("provider not supported: %w", err) + } + + if err := ociClient.LoginWithProvider(ctx, url, ociProvider); err != nil { + return fmt.Errorf("error during login with provider: %w", err) + } + } + opts := oci.ListOptions{ RegexFilter: listArtifactArgs.regexFilter, SemverFilter: listArtifactArgs.semverFilter, diff --git a/cmd/flux/pull_artifact.go b/cmd/flux/pull_artifact.go index f36ab3d0..2fa0eab3 100644 --- a/cmd/flux/pull_artifact.go +++ b/cmd/flux/pull_artifact.go @@ -21,6 +21,8 @@ import ( "fmt" "os" + "github.com/fluxcd/flux2/internal/flags" + sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" "github.com/spf13/cobra" oci "github.com/fluxcd/pkg/oci/client" @@ -30,7 +32,7 @@ var pullArtifactCmd = &cobra.Command{ Use: "artifact", Short: "Pull artifact", Long: `The pull artifact command downloads and extracts the OCI artifact content to the given path. -The pull command uses the credentials from '~/.docker/config.json'.`, +The command can read the credentials from '~/.docker/config.json' but they can also be passed with --creds. It can also login to a supported provider with the --provider flag.`, Example: ` # Pull an OCI artifact created by flux from GHCR flux pull artifact oci://ghcr.io/org/manifests/app:v0.0.1 --output ./path/to/local/manifests `, @@ -38,13 +40,23 @@ The pull command uses the credentials from '~/.docker/config.json'.`, } type pullArtifactFlags struct { - output string + output string + creds string + provider flags.SourceOCIProvider } -var pullArtifactArgs pullArtifactFlags +var pullArtifactArgs = newPullArtifactFlags() + +func newPullArtifactFlags() pullArtifactFlags { + return pullArtifactFlags{ + provider: flags.SourceOCIProvider(sourcev1.GenericOCIProvider), + } +} func init() { pullArtifactCmd.Flags().StringVarP(&pullArtifactArgs.output, "output", "o", "", "path where the artifact content should be extracted.") + pullArtifactCmd.Flags().StringVar(&pullArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format [:] if --provider is generic") + pullArtifactCmd.Flags().Var(&pullArtifactArgs.provider, "provider", sourceOCIRepositoryArgs.provider.Description()) pullCmd.AddCommand(pullArtifactCmd) } @@ -62,7 +74,6 @@ func pullArtifactCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid output path %s", pullArtifactArgs.output) } - ociClient := oci.NewLocalClient() url, err := oci.ParseArtifactURL(ociURL) if err != nil { return err @@ -71,6 +82,27 @@ func pullArtifactCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() + ociClient := oci.NewLocalClient() + + if pullArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && pullArtifactArgs.creds != "" { + logger.Actionf("logging in to registry with credentials") + if err := ociClient.LoginWithCredentials(pullArtifactArgs.creds); err != nil { + return fmt.Errorf("could not login with credentials: %w", err) + } + } + + if pullArtifactArgs.provider.String() != sourcev1.GenericOCIProvider { + logger.Actionf("logging in to registry with provider credentials") + ociProvider, err := pullArtifactArgs.provider.ToOCIProvider() + if err != nil { + return fmt.Errorf("provider not supported: %w", err) + } + + if err := ociClient.LoginWithProvider(ctx, url, ociProvider); err != nil { + return fmt.Errorf("error during login with provider: %w", err) + } + } + logger.Actionf("pulling artifact from %s", url) meta, err := ociClient.Pull(ctx, url, pullArtifactArgs.output) diff --git a/cmd/flux/push_artifact.go b/cmd/flux/push_artifact.go index 75ad0a4e..bc4e0e0d 100644 --- a/cmd/flux/push_artifact.go +++ b/cmd/flux/push_artifact.go @@ -19,9 +19,12 @@ package main import ( "context" "fmt" - "github.com/spf13/cobra" "os" + "github.com/fluxcd/flux2/internal/flags" + sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + "github.com/spf13/cobra" + oci "github.com/fluxcd/pkg/oci/client" ) @@ -29,7 +32,7 @@ var pushArtifactCmd = &cobra.Command{ Use: "artifact", Short: "Push artifact", Long: `The push artifact command creates a tarball from the given directory and uploads the artifact to an OCI repository. -The command uses the credentials from '~/.docker/config.json'.`, +The command can read the credentials from '~/.docker/config.json' but they can also be passed with --creds. It can also login to a supported provider with the --provider flag.`, Example: ` # Push manifests to GHCR using the short Git SHA as the OCI artifact tag echo $GITHUB_PAT | docker login ghcr.io --username flux --password-stdin flux push artifact oci://ghcr.io/org/config/app:$(git rev-parse --short HEAD) \ @@ -43,6 +46,22 @@ The command uses the credentials from '~/.docker/config.json'.`, --path="./path/to/local/manifests" \ --source="$(git config --get remote.origin.url)" \ --revision="$(git tag --points-at HEAD)/$(git rev-parse HEAD)" + + # Login directly to the registry provider + # You might need to export the following variable if you use local config files for AWS: + # export AWS_SDK_LOAD_CONFIG=1 + flux push artifact oci://.dkr.ecr..amazonaws.com/foo:v1:$(git tag --points-at HEAD) \ + --path="./path/to/local/manifests" \ + --source="$(git config --get remote.origin.url)" \ + --revision="$(git tag --points-at HEAD)/$(git rev-parse HEAD)" \ + --provider aws + + # Or pass credentials directly + flux push artifact oci://docker.io/org/app-config:$(git tag --points-at HEAD) \ + --path="./path/to/local/manifests" \ + --source="$(git config --get remote.origin.url)" \ + --revision="$(git tag --points-at HEAD)/$(git rev-parse HEAD)" \ + --creds flux:$DOCKER_PAT `, RunE: pushArtifactCmdRun, } @@ -51,15 +70,25 @@ type pushArtifactFlags struct { path string source string revision string + creds string + provider flags.SourceOCIProvider ignorePaths []string } -var pushArtifactArgs pushArtifactFlags +var pushArtifactArgs = newPushArtifactFlags() + +func newPushArtifactFlags() pushArtifactFlags { + return pushArtifactFlags{ + provider: flags.SourceOCIProvider(sourcev1.GenericOCIProvider), + } +} func init() { pushArtifactCmd.Flags().StringVar(&pushArtifactArgs.path, "path", "", "path to the directory where the Kubernetes manifests are located") pushArtifactCmd.Flags().StringVar(&pushArtifactArgs.source, "source", "", "the source address, e.g. the Git URL") pushArtifactCmd.Flags().StringVar(&pushArtifactArgs.revision, "revision", "", "the source revision in the format '/'") + pushArtifactCmd.Flags().StringVar(&pushArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format [:] if --provider is generic") + pushArtifactCmd.Flags().Var(&pushArtifactArgs.provider, "provider", pushArtifactArgs.provider.Description()) pushArtifactCmd.Flags().StringSliceVar(&pushArtifactArgs.ignorePaths, "ignore-paths", excludeOCI, "set paths to ignore in .gitignore format") pushCmd.AddCommand(pushArtifactCmd) @@ -83,7 +112,6 @@ func pushArtifactCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid path %q", pushArtifactArgs.path) } - ociClient := oci.NewLocalClient() url, err := oci.ParseArtifactURL(ociURL) if err != nil { return err @@ -101,6 +129,27 @@ func pushArtifactCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() + ociClient := oci.NewLocalClient() + + if pushArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && pushArtifactArgs.creds != "" { + logger.Actionf("logging in to registry with credentials") + if err := ociClient.LoginWithCredentials(pushArtifactArgs.creds); err != nil { + return fmt.Errorf("could not login with credentials: %w", err) + } + } + + if pushArtifactArgs.provider.String() != sourcev1.GenericOCIProvider { + logger.Actionf("logging in to registry with provider credentials") + ociProvider, err := pushArtifactArgs.provider.ToOCIProvider() + if err != nil { + return fmt.Errorf("provider not supported: %w", err) + } + + if err := ociClient.LoginWithProvider(ctx, url, ociProvider); err != nil { + return fmt.Errorf("error during login with provider: %w", err) + } + } + logger.Actionf("pushing artifact to %s", url) digest, err := ociClient.Push(ctx, url, pushArtifactArgs.path, meta, pushArtifactArgs.ignorePaths) diff --git a/cmd/flux/tag_artifact.go b/cmd/flux/tag_artifact.go index 65ba1218..0763b697 100644 --- a/cmd/flux/tag_artifact.go +++ b/cmd/flux/tag_artifact.go @@ -20,6 +20,8 @@ import ( "context" "fmt" + "github.com/fluxcd/flux2/internal/flags" + sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" "github.com/spf13/cobra" oci "github.com/fluxcd/pkg/oci/client" @@ -29,7 +31,7 @@ var tagArtifactCmd = &cobra.Command{ Use: "artifact", Short: "Tag artifact", Long: `The tag artifact command creates tags for the given OCI artifact. -The command uses the credentials from '~/.docker/config.json'.`, +The command can read the credentials from '~/.docker/config.json' but they can also be passed with --creds. It can also login to a supported provider with the --provider flag.`, Example: ` # Tag an artifact version as latest flux tag artifact oci://ghcr.io/org/manifests/app:v0.0.1 --tag latest `, @@ -37,13 +39,23 @@ The command uses the credentials from '~/.docker/config.json'.`, } type tagArtifactFlags struct { - tags []string + tags []string + creds string + provider flags.SourceOCIProvider } -var tagArtifactArgs tagArtifactFlags +var tagArtifactArgs = newTagArtifactFlags() + +func newTagArtifactFlags() tagArtifactFlags { + return tagArtifactFlags{ + provider: flags.SourceOCIProvider(sourcev1.GenericOCIProvider), + } +} func init() { tagArtifactCmd.Flags().StringSliceVar(&tagArtifactArgs.tags, "tag", nil, "tag name") + tagArtifactCmd.Flags().StringVar(&tagArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format [:] if --provider is generic") + tagArtifactCmd.Flags().Var(&tagArtifactArgs.provider, "provider", tagArtifactArgs.provider.Description()) tagCmd.AddCommand(tagArtifactCmd) } @@ -57,7 +69,6 @@ func tagArtifactCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("--tag is required") } - ociClient := oci.NewLocalClient() url, err := oci.ParseArtifactURL(ociURL) if err != nil { return err @@ -66,6 +77,27 @@ func tagArtifactCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() + ociClient := oci.NewLocalClient() + + if tagArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && tagArtifactArgs.creds != "" { + logger.Actionf("logging in to registry with credentials") + if err := ociClient.LoginWithCredentials(tagArtifactArgs.creds); err != nil { + return fmt.Errorf("could not login with credentials: %w", err) + } + } + + if tagArtifactArgs.provider.String() != sourcev1.GenericOCIProvider { + logger.Actionf("logging in to registry with provider credentials") + ociProvider, err := tagArtifactArgs.provider.ToOCIProvider() + if err != nil { + return fmt.Errorf("provider not supported: %w", err) + } + + if err := ociClient.LoginWithProvider(ctx, url, ociProvider); err != nil { + return fmt.Errorf("error during login with provider: %w", err) + } + } + logger.Actionf("tagging artifact") for _, tag := range tagArtifactArgs.tags { diff --git a/go.mod b/go.mod index f9a08322..a47badc8 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/fluxcd/notification-controller/api v0.25.2 github.com/fluxcd/pkg/apis/meta v0.15.0 github.com/fluxcd/pkg/kustomize v0.7.0 - github.com/fluxcd/pkg/oci v0.8.0 + github.com/fluxcd/pkg/oci v0.9.0 github.com/fluxcd/pkg/runtime v0.18.0 github.com/fluxcd/pkg/sourceignore v0.2.0 github.com/fluxcd/pkg/ssa v0.19.0 @@ -57,6 +57,9 @@ replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 require ( cloud.google.com/go v0.99.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.27 // indirect @@ -64,10 +67,12 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect github.com/BurntSushi/toml v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/aws/aws-sdk-go v1.44.84 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect @@ -97,6 +102,7 @@ require ( github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.21.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt v3.2.1+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -118,10 +124,12 @@ require ( github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // 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/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/klauspost/compress v1.15.8 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect @@ -142,6 +150,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.13.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect diff --git a/go.sum b/go.sum index 9318730c..2d6034b2 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,12 @@ contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EU dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Antonboom/errname v0.1.5/go.mod h1:DugbBstvPFQbv/5uLcRRzfrNqKE9tVdVCqWCLp6Cifo= github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.2 h1:lneMk5qtUMulXa/eVxjVd+/bDYMEDIqYpLzLa2/EsNI= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.2/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 h1:jp0dGvZ7ZK0mgqnTSClMxa5xuRL7NZgHameVYF6BurY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= 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/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= @@ -73,6 +79,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE= +github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= @@ -126,6 +134,8 @@ github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde/go.mod h1:oG9D github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.44.84 h1:orGogGRrizQSqn3lBnaP/FQIcjPMLf9azDO0h+oTJr0= +github.com/aws/aws-sdk-go v1.44.84/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -198,6 +208,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/distribution/distribution/v3 v3.0.0-20220822034424-3413bf8e14fd h1:jtncyJ6leoRxSuB7y1EkkES0nKuG0kM7arfABcZW9r0= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= @@ -263,8 +274,8 @@ github.com/fluxcd/pkg/apis/meta v0.15.0 h1:uDVzbDNdFjp0GSB9qMpcW6r4K7SAjBQlCxQEN github.com/fluxcd/pkg/apis/meta v0.15.0/go.mod h1:7NkgFrlswnx2QxP16+8zVNDBf+VhZ7PsDhkcJY6OSgQ= github.com/fluxcd/pkg/kustomize v0.7.0 h1:604rlpRZTWaOfzDZ1W93aHaFh9kn8/UMX/wzsjwIUQY= github.com/fluxcd/pkg/kustomize v0.7.0/go.mod h1:zJY3Z0+SX+zs+/A1F6fCT0JvUce265XnrpTtHnujXPo= -github.com/fluxcd/pkg/oci v0.8.0 h1:ky7YemolK/5yGVmw2B8SLn1h4ecrnP38DwCaBOCSDFg= -github.com/fluxcd/pkg/oci v0.8.0/go.mod h1:L+TiQRy92wdqwb2LuScl7T1M24S7IgnzgjBD3iqoKEE= +github.com/fluxcd/pkg/oci v0.9.0 h1:ywS1rp8AV/N4UDVFYQK4qYfrADATPiWA3leXjG/eeK4= +github.com/fluxcd/pkg/oci v0.9.0/go.mod h1:L+TiQRy92wdqwb2LuScl7T1M24S7IgnzgjBD3iqoKEE= github.com/fluxcd/pkg/runtime v0.18.0 h1:3naATapV1y65ZWlsXEfJt66zSQBkJwJ9o/e6gqAF//E= github.com/fluxcd/pkg/runtime v0.18.0/go.mod h1:JKTvOFOCz5Un9KxGcBL7Xjt0fcRa10ZItGB0XFv44AY= github.com/fluxcd/pkg/sourceignore v0.2.0 h1:ooNbIkfxqNB+KKiY4AU+/DxwzjIKIOWBRK1As5QFlug= @@ -353,6 +364,8 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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 v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= @@ -572,7 +585,9 @@ github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSn github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -622,6 +637,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= github.com/kunwardeep/paralleltest v1.0.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/ldez/gomoddirectives v0.2.2/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= @@ -725,6 +741,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= @@ -778,6 +795,9 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -1215,6 +1235,7 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/flags/source_oci_provider.go b/internal/flags/source_oci_provider.go index 5f5067ab..04d9b79a 100644 --- a/internal/flags/source_oci_provider.go +++ b/internal/flags/source_oci_provider.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/fluxcd/flux2/internal/utils" + "github.com/fluxcd/pkg/oci" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" ) @@ -31,6 +32,13 @@ var supportedSourceOCIProviders = []string{ sourcev1.GoogleOCIProvider, } +var sourceOCIProvidersToOCIProvider = map[string]oci.Provider{ + sourcev1.GenericOCIProvider: oci.ProviderGeneric, + sourcev1.AmazonOCIProvider: oci.ProviderAWS, + sourcev1.AzureOCIProvider: oci.ProviderAzure, + sourcev1.GoogleOCIProvider: oci.ProviderGCP, +} + type SourceOCIProvider string func (p *SourceOCIProvider) String() string { @@ -60,3 +68,12 @@ func (p *SourceOCIProvider) Description() string { strings.Join(supportedSourceOCIProviders, ", "), ) } + +func (p *SourceOCIProvider) ToOCIProvider() (oci.Provider, error) { + value, ok := sourceOCIProvidersToOCIProvider[p.String()] + if !ok { + return 0, fmt.Errorf("no mapping between source OCI provider %s and OCI provider", p.String()) + } + + return value, nil +}