1
0
mirror of synced 2026-02-13 13:06:56 +00:00

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 <adrien.fillon@manomano.com>
This commit is contained in:
Adrien Fillon
2022-09-12 10:22:23 +02:00
parent 0c817378cf
commit 0694a9582f
7 changed files with 210 additions and 18 deletions

View File

@@ -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 <username>[:<password>] 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)