Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buf fix #115

Merged
merged 1 commit into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,6 @@ Genval offers comprehensive management capabilities for the configuration files

To bolster supply chain security workflows, Genval enables users to sign the artifacts after storing them in the registry. Similarly, when pulling any artifact, Genval provides functionality to verify the signatures of the artifacts. This feature leverages **Sigstore's Cosign keyless mode** of signing and verifying artifacts. However, users can also utilize their own private and public keys for signing and verifying the artifacts respectively.

To facilitate authentication with container registries, Genval initially looks for the `~/.docker/config.json` file in the user's
`$HOME` directory. If this file is found, Genval utilizes it for authentication with the registry. However, if the file is not present,
users must set the `ARTIFACT_REGISTRY_USERNAME` and `ARTIFACT_REGISTRY_PASSWORD` environment variables to authenticate with the container registry.

#### Building, pushing, and signing generated and/or verified config files and OCI artifacts

The following command demonstrates building and pushing the OCI artifact (genval:test) to GitHub Container Registry (ghcr.io) while signing the artifact with Cosign in Keyless mode:
Expand Down
4 changes: 2 additions & 2 deletions cmd/artifact_pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ func runPullArtifactCmd(cmd *cobra.Command, args []string) error {
defer spin.Stop()

if err := oci.PullArtifact(context.Background(), pullArgs.creds, pullArgs.dest, pullArgs.path); err != nil {
color.Red("Error pulling artifact from remote : %v", err)
return err
fe := color.RedString("Error pulling artifact from remote: %v", err)
return fmt.Errorf(fe)
}
spin.Stop()
color.Green("Artifact from %s pulled and stored in :%s", pullArgs.dest, pullArgs.path)
Expand Down
29 changes: 21 additions & 8 deletions cmd/artifact_push.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package cmd

import (
"context"
"fmt"
"os"
"path/filepath"
"time"

"github.com/fatih/color"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/compression"
"github.com/google/go-containerregistry/pkg/crane"
Expand Down Expand Up @@ -155,21 +157,31 @@ func runPushCmd(cmd *cobra.Command, args []string) error {
if err != nil {
log.Errorf("appending content to artifact failed: %v", err)
}

spin := utils.StartSpinner("pushing artifact")
defer spin.Stop()

var opts []crane.Option
auth, err := oci.GetCreds(pushArgs.creds)
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)
return err
}
opts, err := oci.GenerateCraneOptions(ref, auth, []string{ref.Context().Scope(transport.PushScope)})
if err != nil {
log.Errorf("Error creating options required for push: %v", err)

if pushArgs.creds == "" || auth == nil {
auth, err = authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
return err
}
}

opts = append(opts, crane.WithAuth(auth))
if pushArgs.creds == "" {
opts = append(opts, crane.WithAuthFromKeychain(authn.DefaultKeychain))

topts, err := oci.GenerateCraneOptions(context.Background(), ref.Context().Registry, auth, []string{ref.Context().Scope(transport.PushScope)})
if err != nil {
return fmt.Errorf("error creating transport for push operation: %v", err)
}

opts = append(opts, topts)
if err := crane.Push(img, ref.String(), opts...); err != nil {
log.Fatalf("Error pushing artifact: %v", err)
}
Expand All @@ -188,7 +200,8 @@ func runPushCmd(cmd *cobra.Command, args []string) error {
}
}

log.Infof("✔ Artifact pushed successfully to: %v\n,Artifact Digest: %v\n", source, digest)
log.Infof("Digest URL: %v\n", digestURL)
log.Infof(color.GreenString("✔ Artifact pushed successfully to: %v", pushArgs.dest))
log.Infof(color.GreenString("✔ Digest: %v", digest))
log.Infof(color.GreenString("✔ Digest URL: %v\n", digestURL))
return nil
}
57 changes: 36 additions & 21 deletions pkg/oci/ociClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,26 @@ func CheckTagAndPullArchive(url, tool, creds string, archivePath *os.File) error
ociref := parts[0]
desiredTag := parts[1]

var opts []crane.Option
auth, err := GetCreds(creds)
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)
return fmt.Errorf("error fetching credentials: %v", err)
}
opts, err := GenerateCraneOptions(ref, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
log.Errorf("Error reading credentials: %v", err)

if creds == "" || auth == nil {
auth, err = authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
return fmt.Errorf("error fetching default keychain: %v", err)
}
}

opts = append(opts, crane.WithAuth(auth))
if creds == "" {
opts = append(opts, crane.WithAuthFromKeychain(authn.DefaultKeychain))

topts, err := GenerateCraneOptions(context.Background(), ref.Context().Registry, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
return fmt.Errorf("error creating transport for pull: %v", err)
}
opts = append(opts, topts)

tags, err := crane.ListTags(ociref, opts...)
if err != nil {
Expand Down Expand Up @@ -204,18 +212,26 @@ func PullArtifact(ctx context.Context, creds, dest, path string) error {
url := parts[0]
desiredTag := parts[1]

var opts []crane.Option
auth, err := GetCreds(creds)
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)
return fmt.Errorf("error fetching credentials: %v", err)
}
opts, err := GenerateCraneOptions(ref, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)

if creds == "" || auth == nil {
auth, err = authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
return fmt.Errorf("error fetching default keychain: %v", err)
}
}

opts = append(opts, crane.WithAuth(auth))
if creds == "" {
opts = append(opts, crane.WithAuthFromKeychain(authn.DefaultKeychain))

topts, err := GenerateCraneOptions(context.Background(), ref.Context().Registry, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
return fmt.Errorf("error creating transport for pull:%v", err)
}
opts = append(opts, topts)

tags, err := crane.ListTags(url, opts...)
if err != nil {
Expand Down Expand Up @@ -297,11 +313,11 @@ func GetCreds(creds string) (authn.Authenticator, error) {
}

// Most parts of GenerateCraneOptions and its related funcs are copied from https://github.com/google/go-containerregistry/blob/1b4e4078a545f2b6f96766a064b45ee77cdbefdd/pkg/v1/remote/options.go#L128
func GenerateCraneOptions(ref name.Reference, auth authn.Authenticator, scopes []string) ([]crane.Option, error) {
opts := []crane.Option{}
// GenerateCraneOptions generates an crane options object to perform remote operations
func GenerateCraneOptions(ctx context.Context, ref name.Registry, auth authn.Authenticator, scopes []string) (crane.Option, error) {
var retryTransport http.RoundTripper

userAgent := fmt.Sprintf("intelops/genval/%s (%s; %s)", version.GetVersionInfo().GitVersion, runtime.GOOS, runtime.GOARCH)
userAgent := fmt.Sprintf("genval/%s (%s; %s)", version.GetVersionInfo().GitVersion, runtime.GOOS, runtime.GOARCH)
retryTransport = remote.DefaultTransport.(*http.Transport).Clone()
if logs.Enabled(logs.Debug) {
retryTransport = transport.NewLogger(retryTransport)
Expand All @@ -319,13 +335,12 @@ func GenerateCraneOptions(ref name.Reference, auth authn.Authenticator, scopes [
}))
retryTransport = transport.NewUserAgent(retryTransport, userAgent)

// t, err := transport.NewWithContext(ref.Context().Registry, auth, retryTransport, scopes)
// if err != nil {
// return nil, err
// }
opts = append(opts, crane.WithTransport(retryTransport))
t, err := transport.NewWithContext(ctx, ref, auth, retryTransport, scopes)
if err != nil {
return nil, err
}

return opts, nil
return crane.WithTransport(t), nil
}

var defaultRetryPredicate = func(err error) bool {
Expand Down
Loading