Skip to content

Commit

Permalink
Wrap the crane command to make it easier to use with Zarf (#1205)
Browse files Browse the repository at this point in the history
## Description

This wraps the crane command so that it is easier to use more directly
with Zarf

## Related Issue

Fixes #1186 

## Type of change

- [X] New feature (non-breaking change which adds functionality)

## Checklist before merging

- [X] Documentation has been updated as necessary (add the `needs-docs`
label)
  • Loading branch information
Racer159 authored Jan 17, 2023
1 parent 0dcad90 commit ede3504
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ List the repos in a registry
zarf tools registry catalog [REGISTRY] [flags]
```

### Examples

```
# list the repos internal to Zarf
$ zarf tools registry catalog
# list the repos for reg.example.com
$ zarf tools registry catalog reg.example.com
```

### Options

```
Expand Down
54 changes: 50 additions & 4 deletions src/cmd/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package cmd

import (
"fmt"
"net/url"
"os"

"github.com/anchore/syft/cmd/syft/cli"
Expand All @@ -16,6 +17,7 @@ import (
"github.com/defenseunicorns/zarf/src/pkg/pki"
k9s "github.com/derailed/k9s/cmd"
craneCmd "github.com/google/go-containerregistry/cmd/crane/cmd"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/mholt/archiver/v3"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -153,14 +155,11 @@ func init() {
craneLogin := craneCmd.NewCmdAuthLogin()
craneLogin.Example = ""

craneCatalog := craneCmd.NewCmdCatalog(&cranePlatformOptions)
craneCatalog.Example = ""

registryCmd.AddCommand(craneLogin)
registryCmd.AddCommand(craneCmd.NewCmdPull(&cranePlatformOptions))
registryCmd.AddCommand(craneCmd.NewCmdPush(&cranePlatformOptions))
registryCmd.AddCommand(craneCmd.NewCmdCopy(&cranePlatformOptions))
registryCmd.AddCommand(craneCatalog)
registryCmd.AddCommand(zarfCraneCatalog(&cranePlatformOptions))

syftCmd, err := cli.New()
if err != nil {
Expand All @@ -177,3 +176,50 @@ func init() {

toolsCmd.AddCommand(syftCmd)
}

// Wrap the original crane catalog with a zarf specific version
func zarfCraneCatalog(cranePlatformOptions *[]crane.Option) *cobra.Command {
craneCatalog := craneCmd.NewCmdCatalog(cranePlatformOptions)

eg := ` # list the repos internal to Zarf
$ zarf tools registry catalog
# list the repos for reg.example.com
$ zarf tools registry catalog reg.example.com`

craneCatalog.Example = eg
craneCatalog.Args = nil

originalCatalogFn := craneCatalog.RunE

craneCatalog.RunE = func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
return originalCatalogFn(cmd, args)
}

// Load Zarf state
zarfState, err := cluster.NewClusterOrDie().LoadZarfState()
if err != nil {
return err
}

// Open a tunnel to the Zarf registry
tunnelReg, err := cluster.NewZarfTunnel()
if err != nil {
return err
}
tunnelReg.Connect(cluster.ZarfRegistry, false)
registryURL, err := url.Parse(tunnelReg.HTTPEndpoint())
if err != nil {
return err
}

// Add the correct authentication to the crane command options
authOption := config.GetCraneAuthOption(zarfState.RegistryInfo.PullUsername, zarfState.RegistryInfo.PullPassword)
*cranePlatformOptions = append(*cranePlatformOptions, authOption)

return originalCatalogFn(cmd, []string{registryURL.Host})
}

return craneCatalog
}
43 changes: 8 additions & 35 deletions src/test/e2e/21_connect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
package test

import (
"encoding/base64"
"encoding/json"
"io"
"net/http"
"strings"
"testing"

"github.com/defenseunicorns/zarf/src/internal/cluster"
Expand All @@ -25,38 +23,13 @@ func TestConnect(t *testing.T) {
e2e.setupWithCluster(t)
defer e2e.teardown(t)

// Get the state from the cluster
zarfState, err := cluster.NewClusterOrDie().LoadZarfState()
require.NoError(t, err)

// Connect to the Registry
tunnelReg, err := cluster.NewZarfTunnel()
require.NoError(t, err)
tunnelReg.Connect(cluster.ZarfRegistry, false)
defer tunnelReg.Close()

// Make the Registry contains the images we expect
reqReg, err := http.NewRequest("GET", tunnelReg.HTTPEndpoint()+"/v2/_catalog", nil)
assert.NoError(t, err)

authReg := zarfState.RegistryInfo.PullUsername + ":" + zarfState.RegistryInfo.PullPassword
authRegB64 := base64.StdEncoding.EncodeToString([]byte(authReg))
reqReg.Header.Add("Authorization", "Basic "+authRegB64)

respReg, err := http.DefaultClient.Do(reqReg)
assert.NoError(t, err)
assert.Equal(t, 200, respReg.StatusCode)

bodyReg, err := io.ReadAll(respReg.Body)
defer respReg.Body.Close()
assert.NoError(t, err)

registries := RegistryResponse{}
err = json.Unmarshal(bodyReg, &registries)
assert.NoError(t, err)
assert.Equal(t, 12, len(registries.Repositories))
assert.Contains(t, registries.Repositories, "gitea/gitea")
assert.Contains(t, registries.Repositories, "gitea/gitea-3431384023")
stdOut, stdErr, err := e2e.execZarfCommand("tools", "registry", "catalog")
assert.NoError(t, err, stdOut, stdErr)
registryList := strings.Split(strings.Trim(stdOut, "\n "), "\n")
assert.Equal(t, 12, len(registryList))
assert.Contains(t, stdOut, "gitea/gitea")
assert.Contains(t, stdOut, "gitea/gitea-3431384023")

// Connect to Gitea
tunnelGit, err := cluster.NewZarfTunnel()
Expand All @@ -80,6 +53,6 @@ func TestConnect(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 200, respLog.StatusCode)

stdOut, stdErr, err := e2e.execZarfCommand("package", "remove", "init", "--components=logging", "--confirm")
stdOut, stdErr, err = e2e.execZarfCommand("package", "remove", "init", "--components=logging", "--confirm")
require.NoError(t, err, stdOut, stdErr)
}

0 comments on commit ede3504

Please sign in to comment.