diff --git a/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry.md b/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry.md index 0a60fa5671..324d1464f3 100644 --- a/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry.md +++ b/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry.md @@ -19,5 +19,6 @@ Tools for working with container registries using go-containertools * [zarf tools registry catalog](zarf_tools_registry_catalog.md) - List the repos in a registry * [zarf tools registry copy](zarf_tools_registry_copy.md) - Efficiently copy a remote image from src to dst while retaining the digest value * [zarf tools registry login](zarf_tools_registry_login.md) - Log in to a registry +* [zarf tools registry ls](zarf_tools_registry_ls.md) - List the tags in a repo * [zarf tools registry pull](zarf_tools_registry_pull.md) - Pull remote images by reference and store their contents locally * [zarf tools registry push](zarf_tools_registry_push.md) - Push local image contents to a remote registry diff --git a/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry_ls.md b/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry_ls.md new file mode 100644 index 0000000000..8976ea496e --- /dev/null +++ b/docs/2-the-zarf-cli/100-cli-commands/zarf_tools_registry_ls.md @@ -0,0 +1,41 @@ +# zarf tools registry ls + + +List the tags in a repo + +``` +zarf tools registry ls REPO [flags] +``` + +## Examples + +``` + + # list the tags for a repo internal to Zarf + $ zarf tools registry ls 127.0.0.1:31999/stefanprodan/podinfo + + # list the tags for a repo hosted at reg.example.com + $ zarf tools registry ls reg.example.com/stefanprodan/podinfo + +``` + +## Options + +``` + --full-ref (Optional) if true, print the full image reference + -h, --help help for ls + --omit-digest-tags (Optional), if true, omit digest tags (e.g., ':sha256-...') +``` + +## Options inherited from parent commands + +``` + --allow-nondistributable-artifacts Allow pushing non-distributable (foreign) layers + --insecure Allow image references to be fetched without TLS + --platform string Specifies the platform in the form os/arch[/variant][:osversion] (e.g. linux/amd64). (default "all") + -v, --verbose Enable debug logs +``` + +## SEE ALSO + +* [zarf tools registry](zarf_tools_registry.md) - Tools for working with container registries using go-containertools diff --git a/src/cmd/tools/crane.go b/src/cmd/tools/crane.go index 0c1985c216..92f031acbd 100644 --- a/src/cmd/tools/crane.go +++ b/src/cmd/tools/crane.go @@ -5,8 +5,7 @@ package tools import ( - "os" - + "fmt" "github.com/defenseunicorns/zarf/src/config" "github.com/defenseunicorns/zarf/src/config/lang" "github.com/defenseunicorns/zarf/src/internal/cluster" @@ -16,6 +15,8 @@ import ( "github.com/google/go-containerregistry/pkg/logs" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/spf13/cobra" + "os" + "strings" ) func init() { @@ -69,6 +70,7 @@ func init() { registryCmd.AddCommand(craneCopy) registryCmd.AddCommand(zarfCraneCatalog(&craneOptions)) + registryCmd.AddCommand(zarfCraneList(&craneOptions)) registryCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, lang.CmdToolsRegistryFlagVerbose) registryCmd.PersistentFlags().BoolVar(&insecure, "insecure", false, lang.CmdToolsRegistryFlagInsecure) @@ -118,3 +120,60 @@ func zarfCraneCatalog(cranePlatformOptions *[]crane.Option) *cobra.Command { return craneCatalog } + +// Wrap the original crane list with a zarf specific version +func zarfCraneList(cranePlatformOptions *[]crane.Option) *cobra.Command { + craneList := craneCmd.NewCmdList(cranePlatformOptions) + + craneList.Example = lang.CmdToolsRegistryListExample + craneList.Args = nil + + originalListFn := craneList.RunE + + craneList.RunE = func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + message.Fatal(nil, lang.CmdToolsCraneListNoRepoSpecified) + } + + // Try to connect to a Zarf initialized cluster otherwise then pass it down to crane. + zarfCluster, err := cluster.NewCluster() + if err != nil { + return originalListFn(cmd, args) + } + + // Load the state + zarfState, err := zarfCluster.LoadZarfState() + if err != nil { + return err + } + + // Check to see if it matches the existing internal address. + if !strings.HasPrefix(args[0], zarfState.RegistryInfo.Address) { + return originalListFn(cmd, args) + } + + if zarfState.RegistryInfo.InternalRegistry { + // Open a tunnel to the Zarf registry + tunnelReg, err := cluster.NewZarfTunnel() + if err != nil { + return err + } + err = tunnelReg.Connect(cluster.ZarfRegistry, false) + if err != nil { + return err + } + + givenAddress := fmt.Sprintf("%s/", zarfState.RegistryInfo.Address) + tunnelAddress := fmt.Sprintf("%s/", tunnelReg.Endpoint()) + args[0] = strings.Replace(args[0], givenAddress, tunnelAddress, 1) + } + + // Add the correct authentication to the crane command options + authOption := config.GetCraneAuthOption(zarfState.RegistryInfo.PullUsername, zarfState.RegistryInfo.PullPassword) + *cranePlatformOptions = append(*cranePlatformOptions, authOption) + + return originalListFn(cmd, args) + } + + return craneList +} diff --git a/src/config/lang/english.go b/src/config/lang/english.go index 8533be186c..1e909a2ed3 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -332,6 +332,14 @@ const ( # list the repos for reg.example.com $ zarf tools registry catalog reg.example.com ` + CmdToolsRegistryListExample = ` + # list the tags for a repo internal to Zarf + $ zarf tools registry ls 127.0.0.1:31999/stefanprodan/podinfo + + # list the tags for a repo hosted at reg.example.com + $ zarf tools registry ls reg.example.com/stefanprodan/podinfo +` + CmdToolsRegistryInvalidPlatformErr = "Invalid platform '%s': %s" CmdToolsRegistryFlagVerbose = "Enable debug logs" CmdToolsRegistryFlagInsecure = "Allow image references to be fetched without TLS" @@ -351,6 +359,8 @@ const ( CmdToolsClearCacheSuccess = "Successfully cleared the cache from %s" CmdToolsClearCacheFlagCachePath = "Specify the location of the Zarf artifact cache (images and git repositories)" + CmdToolsCraneListNoRepoSpecified = "You must specify a repository name to return a list of tags for." + CmdToolsDownloadInitShort = "Downloads the init package for the current Zarf version into the specified directory" CmdToolsDownloadInitFlagOutputDirectory = "Specify a directory to place the init package in." CmdToolsDownloadInitErr = "Unable to download the init package: %s"