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

Client go containerregistry #71

Closed
wants to merge 5 commits into from
Closed
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
5 changes: 2 additions & 3 deletions v2/client/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import (
"context"
"path"

"github.com/docker/distribution/reference"
voucher "github.com/grafeas/voucher/v2"
)

// Check executes a request to a Voucher server, to the appropriate check URI, and
// with the passed reference.Canonical. Returns a voucher.Response and an error.
func (c *Client) Check(ctx context.Context, check string, image reference.Canonical) (voucher.Response, error) {
// with the passed image. Returns a voucher.Response and an error.
func (c *Client) Check(ctx context.Context, check string, image string) (voucher.Response, error) {
url := c.toVoucherCheckURL(check)
resp, err := c.doVoucherRequest(ctx, url, image)
if err != nil {
Expand Down
7 changes: 3 additions & 4 deletions v2/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"net/url"
"strings"

"github.com/docker/distribution/reference"
voucher "github.com/grafeas/voucher/v2"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
Expand Down Expand Up @@ -145,9 +144,9 @@ func (c *Client) CopyURL() *url.URL {
return &urlCopy
}

func (c *Client) newVoucherRequest(ctx context.Context, url string, image reference.Canonical) (*http.Request, error) {
func (c *Client) newVoucherRequest(ctx context.Context, url string, image string) (*http.Request, error) {
voucherReq := voucher.Request{
ImageURL: image.String(),
ImageURL: image,
}

var buf bytes.Buffer
Expand All @@ -168,7 +167,7 @@ func (c *Client) newVoucherRequest(ctx context.Context, url string, image refere
return req, nil
}

func (c *Client) doVoucherRequest(ctx context.Context, url string, image reference.Canonical) (*voucher.Response, error) {
func (c *Client) doVoucherRequest(ctx context.Context, url string, image string) (*voucher.Response, error) {
req, err := c.newVoucherRequest(ctx, url, image)
if err != nil {
return nil, fmt.Errorf("could create voucher request: %w", err)
Expand Down
15 changes: 3 additions & 12 deletions v2/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"
"testing"

"github.com/docker/distribution/reference"
"github.com/grafeas/voucher/v2"
"github.com/grafeas/voucher/v2/client"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -57,7 +56,7 @@ func TestVoucher_Check(t *testing.T) {

c, err := client.NewClient(srv.URL)
require.NoError(t, err)
res, err := c.Check(context.Background(), "diy", canonical(t, image))
res, err := c.Check(context.Background(), "diy", image)
require.NoError(t, err)
assert.True(t, res.Success)
}
Expand All @@ -72,7 +71,7 @@ func TestVoucher_CustomUserAgent(t *testing.T) {

c, err := client.NewClientContext(context.Background(), srv.URL, client.WithUserAgent(customUserAgent))
require.NoError(t, err)
res, err := c.Check(context.Background(), "diy", canonical(t, image))
res, err := c.Check(context.Background(), "diy", image)
require.NoError(t, err)
assert.True(t, res.Success)
}
Expand All @@ -85,7 +84,7 @@ func TestVoucher_Verify(t *testing.T) {

c, err := client.NewClient(srv.URL)
require.NoError(t, err)
res, err := c.Verify(context.Background(), "diy", canonical(t, image))
res, err := c.Verify(context.Background(), "diy", image)
require.NoError(t, err)
assert.True(t, res.Success)
}
Expand Down Expand Up @@ -135,11 +134,3 @@ func (v *mockVoucher) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(res)
}

func canonical(t *testing.T, image string) reference.Canonical {
ref, err := reference.Parse(image)
require.NoError(t, err)
canonical, ok := ref.(reference.Canonical)
require.True(t, ok)
return canonical
}
4 changes: 1 addition & 3 deletions v2/client/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import (
"context"
"path"

"github.com/docker/distribution/reference"

voucher "github.com/grafeas/voucher/v2"
)

func (c *Client) Verify(ctx context.Context, check string, image reference.Canonical) (voucher.Response, error) {
func (c *Client) Verify(ctx context.Context, check string, image string) (voucher.Response, error) {
url := c.toVoucherVerifyURL(check)
resp, err := c.doVoucherRequest(ctx, url, image)
if err != nil {
Expand Down
5 changes: 0 additions & 5 deletions v2/cmd/voucher_client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"strings"
"time"

voucher "github.com/grafeas/voucher/v2"
"github.com/grafeas/voucher/v2/client"
Expand Down Expand Up @@ -41,7 +40,3 @@ func getVoucherClient(ctx context.Context) (voucher.Interface, error) {
}
return client.NewClientContext(ctx, defaultConfig.Server, options...)
}

func newContext() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), time.Duration(defaultConfig.Timeout)*time.Second)
}
37 changes: 0 additions & 37 deletions v2/cmd/voucher_client/digest.go

This file was deleted.

38 changes: 0 additions & 38 deletions v2/cmd/voucher_client/lookup.go

This file was deleted.

40 changes: 0 additions & 40 deletions v2/cmd/voucher_client/output.go

This file was deleted.

79 changes: 74 additions & 5 deletions v2/cmd/voucher_client/root.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package main

import (
"context"
"errors"
"fmt"
"os"
"time"

"github.com/google/go-containerregistry/pkg/v1/google"
voucher "github.com/grafeas/voucher/v2"
"github.com/grafeas/voucher/v2/container"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand All @@ -19,7 +24,7 @@ var (
var rootCmd = &cobra.Command{
Use: "voucher_client",
Short: "voucher_client sends images to a Voucher server to be reviewed",
Long: `voucher_client is a frontend for Voucher server, which allows users to send
Long: `voucher_client is a frontend for Voucher server, which allows users to send
images for analysis. It automatically resolves tags to digests when it encounters
them.`,
Args: func(cmd *cobra.Command, args []string) error {
Expand All @@ -29,14 +34,78 @@ them.`,
return nil
},
Run: func(cmd *cobra.Command, args []string) {
if verify {
LookupAndVerify(args)
return
if err := clientRun(args); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
LookupAndCheck(args)
},
}

func clientRun(args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(defaultConfig.Timeout)*time.Second)
defer cancel()

// Attempt google auth, but don't worry if it fails:
googleAuth, _ := google.NewEnvAuthenticator()
resolver := container.NewResolver(googleAuth)
digest, err := resolver.ToDigest(ctx, args[0])
if err != nil {
return fmt.Errorf("getting canonical reference failed: %w", err)
}

client, err := getVoucherClient(ctx)
if err != nil {
return fmt.Errorf("creating client failed: %w", err)
}
var op func(context.Context, string, string) (voucher.Response, error)
if verify {
op = client.Verify
fmt.Printf("Verifying %s\n", digest)
} else {
op = client.Check
fmt.Printf("Checking %s\n", digest)
}

resp, err := op(ctx, getCheck(), digest.String())
if err != nil {
return fmt.Errorf("remote operation failed: %w", err)
}
fmt.Println(formatResponse(&resp))

if !resp.Success {
return fmt.Errorf("image failed to pass required check(s)")
}

return nil
}

// formatResponse returns the response as a string.
func formatResponse(resp *voucher.Response) string {
output := ""
if resp.Success {
fmt.Println("image is approved")
} else {
fmt.Println("image was rejected")
}
for _, result := range resp.Results {
if result.Success {
output += fmt.Sprintf(" ✓ passed %s", result.Name)
if !result.Attested {
output += ", but wasn't attested"
}
} else {
output += fmt.Sprintf(" ✗ failed %s", result.Name)
}

if "" != result.Err {
output += fmt.Sprintf(", err: %s", result.Err)
}
output += "\n"
}

return output
}

// init initializes the configuration and the flags.
func init() {
cobra.OnInitialize(initConfig)
Expand Down
Loading