From 1a2e27824a351a69fc34b8967a8a1c96f83ef82e Mon Sep 17 00:00:00 2001 From: Catalin Date: Thu, 18 Apr 2024 15:04:21 +0300 Subject: [PATCH 1/6] implemented search cli command to return found packages from configured ghcr.io registry in table format --- cmd/kndp/main.go | 2 + cmd/kndp/search/search.go | 112 ++++++++++++++++++++++++++++++++++++++ go.mod | 3 + go.sum | 7 +++ 4 files changed, 124 insertions(+) create mode 100644 cmd/kndp/search/search.go diff --git a/cmd/kndp/main.go b/cmd/kndp/main.go index ee03eb0..6ad1e8f 100644 --- a/cmd/kndp/main.go +++ b/cmd/kndp/main.go @@ -10,6 +10,7 @@ import ( "github.com/kndpio/kndp/cmd/kndp/configuration" "github.com/kndpio/kndp/cmd/kndp/environment" "github.com/kndpio/kndp/cmd/kndp/provider" + "github.com/kndpio/kndp/cmd/kndp/search" "github.com/kndpio/kndp/internal/kube" "github.com/kndpio/kndp/cmd/kndp/registry" @@ -70,6 +71,7 @@ type cli struct { Registry registry.Cmd `cmd:"" name:"registry" aliases:"reg" help:"Packages registy commands"` InstallCompletions kongplete.InstallCompletions `cmd:"" help:"Install shell completions"` Provider provider.Cmd `cmd:"" name:"provider" help:"KNDP Provider commands"` + Search search.SearchCmd `cmd:"" help:"Search for packages"` } type helpCmd struct{} diff --git a/cmd/kndp/search/search.go b/cmd/kndp/search/search.go new file mode 100644 index 0000000..26166c4 --- /dev/null +++ b/cmd/kndp/search/search.go @@ -0,0 +1,112 @@ +package search + +import ( + "context" + "encoding/json" + + "net/url" + "strings" + + "github.com/charmbracelet/log" + "github.com/google/go-github/v61/github" + "github.com/kndpio/kndp/internal/registry" + "github.com/pterm/pterm" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +// SearchCmd is the struct representing the search command +type SearchCmd struct { + // Query is the search query + Query string `arg:"" help:"search query"` + Versions bool `optional:"" short:"v" help:"display all versions"` +} + +func getTableRegs(ctx context.Context, clientgh *github.Client, org string, query string, pkgType string, allVersions bool, logger *log.Logger) (pterm.TableData, error) { + tableRegs := pterm.TableData{ + {"URL", "VERSION"}, + } + + pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) + if err != nil { + logger.Error("Cannot get packages") + return nil, err + } + + for _, pkg := range pkgs { + // Filter packages based on the query + if !strings.Contains(*pkg.Name, query) { + continue + } + + pkgVersions, _, err := clientgh.Organizations.PackageGetAllVersions(ctx, org, pkgType, pkg.GetName(), nil) + if err != nil { + logger.Error("Cannot get package versions") + return nil, err + } + + var latestVersion *github.PackageVersion + for _, v := range pkgVersions { + tags := v.GetMetadata().Container.Tags + if len(tags) > 0 { + if !allVersions { + latestVersion = v + break + } + tableRegs = append(tableRegs, []string{ + "ghcr.io/" + org + "/" + *pkg.Name, + tags[0], + }) + } + } + + if latestVersion != nil { + tags := latestVersion.GetMetadata().Container.Tags + if len(tags) > 0 { + tableRegs = append(tableRegs, []string{ + "ghcr.io/" + org + "/" + *pkg.Name, + tags[0], + }) + } + } + } + + return tableRegs, nil +} + +func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, logger *log.Logger) error { + var pkgType = "container" + registries, err := registry.Registries(ctx, client) + if err != nil { + logger.Error("Cannot get registries") + return err + } + + for _, r := range registries { + registryUrl := r.Annotations["kndp-registry-server-url"] + u, _ := url.Parse(registryUrl) + org := strings.TrimPrefix(u.Path, "/") + + if strings.Contains(registryUrl, "ghcr.io") { + auth := registry.RegistryConfig{} + json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) + clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) + + tableRegs, err := getTableRegs(ctx, clientgh, org, c.Query, pkgType, c.Versions, logger) + if err != nil { + logger.Error("Cannot get table registries") + } + if len(tableRegs) <= 1 { + logger.Info("No packages found") + return nil + } else { + pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() + } + + } else { + logger.Errorf("Registry not supported %s", registryUrl) + } + } + + return nil +} diff --git a/go.mod b/go.mod index e37e498..07915dd 100644 --- a/go.mod +++ b/go.mod @@ -75,6 +75,8 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-github v17.0.0+incompatible // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.4.0 // indirect @@ -186,6 +188,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/go-playground/validator/v10 v10.18.0 github.com/google/go-containerregistry v0.19.0 + github.com/google/go-github/v61 v61.0.0 github.com/mattn/go-runewidth v0.0.15 // indirect github.com/pterm/pterm v0.12.79 github.com/rivo/uniseg v0.4.4 // indirect diff --git a/go.sum b/go.sum index c9e35f9..74d529f 100644 --- a/go.sum +++ b/go.sum @@ -245,12 +245,19 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic= github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= +github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= +github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= From 4e08dd5f7d58d9abe321e0b51b16e83cdb7f41ab Mon Sep 17 00:00:00 2001 From: Catalin Date: Thu, 18 Apr 2024 16:04:47 +0300 Subject: [PATCH 2/6] added switcher to handle multiple registry types, moved github registry search to internal packages --- cmd/kndp/search/search.go | 83 +++++---------------------------------- go.mod | 2 +- go.sum | 3 -- internal/search/search.go | 79 +++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 78 deletions(-) create mode 100644 internal/search/search.go diff --git a/cmd/kndp/search/search.go b/cmd/kndp/search/search.go index 26166c4..97e3eab 100644 --- a/cmd/kndp/search/search.go +++ b/cmd/kndp/search/search.go @@ -2,15 +2,13 @@ package search import ( "context" - "encoding/json" "net/url" "strings" "github.com/charmbracelet/log" - "github.com/google/go-github/v61/github" "github.com/kndpio/kndp/internal/registry" - "github.com/pterm/pterm" + "github.com/kndpio/kndp/internal/search" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -22,90 +20,27 @@ type SearchCmd struct { Versions bool `optional:"" short:"v" help:"display all versions"` } -func getTableRegs(ctx context.Context, clientgh *github.Client, org string, query string, pkgType string, allVersions bool, logger *log.Logger) (pterm.TableData, error) { - tableRegs := pterm.TableData{ - {"URL", "VERSION"}, - } - - pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) - if err != nil { - logger.Error("Cannot get packages") - return nil, err - } - - for _, pkg := range pkgs { - // Filter packages based on the query - if !strings.Contains(*pkg.Name, query) { - continue - } - - pkgVersions, _, err := clientgh.Organizations.PackageGetAllVersions(ctx, org, pkgType, pkg.GetName(), nil) - if err != nil { - logger.Error("Cannot get package versions") - return nil, err - } - - var latestVersion *github.PackageVersion - for _, v := range pkgVersions { - tags := v.GetMetadata().Container.Tags - if len(tags) > 0 { - if !allVersions { - latestVersion = v - break - } - tableRegs = append(tableRegs, []string{ - "ghcr.io/" + org + "/" + *pkg.Name, - tags[0], - }) - } - } - - if latestVersion != nil { - tags := latestVersion.GetMetadata().Container.Tags - if len(tags) > 0 { - tableRegs = append(tableRegs, []string{ - "ghcr.io/" + org + "/" + *pkg.Name, - tags[0], - }) - } - } - } - - return tableRegs, nil -} - func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, logger *log.Logger) error { - var pkgType = "container" registries, err := registry.Registries(ctx, client) if err != nil { logger.Error("Cannot get registries") return err } - for _, r := range registries { registryUrl := r.Annotations["kndp-registry-server-url"] u, _ := url.Parse(registryUrl) org := strings.TrimPrefix(u.Path, "/") - - if strings.Contains(registryUrl, "ghcr.io") { - auth := registry.RegistryConfig{} - json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) - clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) - - tableRegs, err := getTableRegs(ctx, clientgh, org, c.Query, pkgType, c.Versions, logger) + // Switch statement to handle different registry types + switch { + case strings.Contains(registryUrl, "ghcr.io"): + err := search.GitHubreg(ctx, c.Query, c.Versions, r, registryUrl, org, logger) if err != nil { - logger.Error("Cannot get table registries") + return err } - if len(tableRegs) <= 1 { - logger.Info("No packages found") - return nil - } else { - pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() - } - - } else { - logger.Errorf("Registry not supported %s", registryUrl) + default: + search.GitHubreg(ctx, c.Query, c.Versions, r, registryUrl, org, logger) } + } return nil diff --git a/go.mod b/go.mod index 8d3273a..1d2b474 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-github v17.0.0+incompatible // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect diff --git a/go.sum b/go.sum index 0d40a29..eb5d362 100644 --- a/go.sum +++ b/go.sum @@ -245,14 +245,11 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic= github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= diff --git a/internal/search/search.go b/internal/search/search.go new file mode 100644 index 0000000..dec8162 --- /dev/null +++ b/internal/search/search.go @@ -0,0 +1,79 @@ +package search + +import ( + "context" + "encoding/json" + "strings" + + "github.com/charmbracelet/log" + "github.com/kndpio/kndp/internal/registry" + + "github.com/google/go-github/v61/github" + "github.com/pterm/pterm" +) + +// GitHubreg search for packages in GitHub Container Registry +func GitHubreg(ctx context.Context, query string, versions bool, r *registry.Registry, registryUrl string, org string, logger *log.Logger) error { + auth := registry.RegistryConfig{} + json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) + clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) + + pkgType := "container" + + tableRegs := pterm.TableData{ + {"URL", "VERSION"}, + } + + pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) + if err != nil { + logger.Errorf("Cannot get packages from %s", registryUrl) + return err + } + + for _, pkg := range pkgs { + // Filter packages based on the query + if !strings.Contains(*pkg.Name, query) { + continue + } + + pkgVersions, _, err := clientgh.Organizations.PackageGetAllVersions(ctx, org, pkgType, pkg.GetName(), nil) + if err != nil { + logger.Errorf("Cannot get package versions %s", registryUrl) + return err + } + + var latestVersion *github.PackageVersion + for _, v := range pkgVersions { + tags := v.GetMetadata().Container.Tags + if len(tags) > 0 { + if !versions { + latestVersion = v + break + } + tableRegs = append(tableRegs, []string{ + "ghcr.io/" + org + "/" + *pkg.Name, + tags[0], + }) + } + } + + if latestVersion != nil { + tags := latestVersion.GetMetadata().Container.Tags + if len(tags) > 0 { + tableRegs = append(tableRegs, []string{ + "ghcr.io/" + org + "/" + *pkg.Name, + tags[0], + }) + } + } + } + + if len(tableRegs) <= 1 { + logger.Info("No packages found") + return nil + } else { + pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() + } + return nil + +} From a86c40bd3035ebc7e5caad16ee1a25c9eaa0be90 Mon Sep 17 00:00:00 2001 From: Catalin Date: Fri, 19 Apr 2024 16:13:27 +0300 Subject: [PATCH 3/6] moved search implementation into registry package, return github packages data instead of table regs --- cmd/kndp/main.go | 3 +- cmd/kndp/{search => registry}/search.go | 35 +++++++++-- internal/registry/github.go | 42 +++++++++++++ internal/search/search.go | 79 ------------------------- 4 files changed, 74 insertions(+), 85 deletions(-) rename cmd/kndp/{search => registry}/search.go (53%) create mode 100644 internal/registry/github.go delete mode 100644 internal/search/search.go diff --git a/cmd/kndp/main.go b/cmd/kndp/main.go index 84c4026..e2d8b1d 100644 --- a/cmd/kndp/main.go +++ b/cmd/kndp/main.go @@ -10,7 +10,6 @@ import ( "github.com/kndpio/kndp/cmd/kndp/configuration" "github.com/kndpio/kndp/cmd/kndp/environment" "github.com/kndpio/kndp/cmd/kndp/provider" - "github.com/kndpio/kndp/cmd/kndp/search" "github.com/kndpio/kndp/internal/kube" "github.com/kndpio/kndp/cmd/kndp/registry" @@ -72,7 +71,7 @@ type cli struct { Registry registry.Cmd `cmd:"" name:"registry" aliases:"reg" help:"Packages registy commands"` InstallCompletions kongplete.InstallCompletions `cmd:"" help:"Install shell completions"` Provider provider.Cmd `cmd:"" name:"provider" help:"KNDP Provider commands"` - Search search.SearchCmd `cmd:"" help:"Search for packages"` + Search registry.SearchCmd `cmd:"" help:"Search for packages"` } type helpCmd struct{} diff --git a/cmd/kndp/search/search.go b/cmd/kndp/registry/search.go similarity index 53% rename from cmd/kndp/search/search.go rename to cmd/kndp/registry/search.go index 97e3eab..1ec9de7 100644 --- a/cmd/kndp/search/search.go +++ b/cmd/kndp/registry/search.go @@ -1,4 +1,4 @@ -package search +package registry import ( "context" @@ -8,7 +8,7 @@ import ( "github.com/charmbracelet/log" "github.com/kndpio/kndp/internal/registry" - "github.com/kndpio/kndp/internal/search" + "github.com/pterm/pterm" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -26,6 +26,9 @@ func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, confi logger.Error("Cannot get registries") return err } + tableRegs := pterm.TableData{ + {"URL", "VERSION"}, + } for _, r := range registries { registryUrl := r.Annotations["kndp-registry-server-url"] u, _ := url.Parse(registryUrl) @@ -33,12 +36,36 @@ func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, confi // Switch statement to handle different registry types switch { case strings.Contains(registryUrl, "ghcr.io"): - err := search.GitHubreg(ctx, c.Query, c.Versions, r, registryUrl, org, logger) + pkgs, pkgVersions, err := registry.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) if err != nil { return err } + for _, pkg := range pkgs { + if !strings.Contains(*pkg.Name, c.Query) { + continue + } + versions := pkgVersions[*pkg.Name] + for _, v := range versions { + tags := v.GetMetadata().Container.Tags + if len(tags) > 0 { + tableRegs = append(tableRegs, []string{ + "ghcr.io/" + org + "/" + *pkg.Name, + tags[0], + }) + } + } + } + if len(tableRegs) <= 1 { + logger.Info("No packages found") + } else { + pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() + } + default: - search.GitHubreg(ctx, c.Query, c.Versions, r, registryUrl, org, logger) + _, _, err := registry.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) + if err != nil { + return err + } } } diff --git a/internal/registry/github.go b/internal/registry/github.go new file mode 100644 index 0000000..10dcfc4 --- /dev/null +++ b/internal/registry/github.go @@ -0,0 +1,42 @@ +package registry + +import ( + "context" + "encoding/json" + + "github.com/charmbracelet/log" + + "github.com/google/go-github/v61/github" +) + +// GetGithubPackages list packages and their versions from GitHub Container Registry +func GetGithubPackages(ctx context.Context, query string, version bool, r *Registry, registryUrl string, org string, logger *log.Logger) ([]*github.Package, map[string][]*github.PackageVersion, error) { + auth := RegistryConfig{} + json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) + clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) + + pkgType := "container" + + pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) + if err != nil { + logger.Errorf("Cannot get packages from %s", registryUrl) + return nil, nil, err + } + + pkgVersions := make(map[string][]*github.PackageVersion) + for _, pkg := range pkgs { + versions, _, err := clientgh.Organizations.PackageGetAllVersions(ctx, org, pkgType, pkg.GetName(), nil) + if err != nil { + logger.Errorf("Cannot get package versions for %s/%s", org, *pkg.Name) + return nil, nil, err + } + if !version { + if len(versions) > 0 { + pkgVersions[*pkg.Name] = []*github.PackageVersion{versions[0]} + } + } else { + pkgVersions[*pkg.Name] = versions + } + } + return pkgs, pkgVersions, nil +} diff --git a/internal/search/search.go b/internal/search/search.go deleted file mode 100644 index dec8162..0000000 --- a/internal/search/search.go +++ /dev/null @@ -1,79 +0,0 @@ -package search - -import ( - "context" - "encoding/json" - "strings" - - "github.com/charmbracelet/log" - "github.com/kndpio/kndp/internal/registry" - - "github.com/google/go-github/v61/github" - "github.com/pterm/pterm" -) - -// GitHubreg search for packages in GitHub Container Registry -func GitHubreg(ctx context.Context, query string, versions bool, r *registry.Registry, registryUrl string, org string, logger *log.Logger) error { - auth := registry.RegistryConfig{} - json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) - clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) - - pkgType := "container" - - tableRegs := pterm.TableData{ - {"URL", "VERSION"}, - } - - pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) - if err != nil { - logger.Errorf("Cannot get packages from %s", registryUrl) - return err - } - - for _, pkg := range pkgs { - // Filter packages based on the query - if !strings.Contains(*pkg.Name, query) { - continue - } - - pkgVersions, _, err := clientgh.Organizations.PackageGetAllVersions(ctx, org, pkgType, pkg.GetName(), nil) - if err != nil { - logger.Errorf("Cannot get package versions %s", registryUrl) - return err - } - - var latestVersion *github.PackageVersion - for _, v := range pkgVersions { - tags := v.GetMetadata().Container.Tags - if len(tags) > 0 { - if !versions { - latestVersion = v - break - } - tableRegs = append(tableRegs, []string{ - "ghcr.io/" + org + "/" + *pkg.Name, - tags[0], - }) - } - } - - if latestVersion != nil { - tags := latestVersion.GetMetadata().Container.Tags - if len(tags) > 0 { - tableRegs = append(tableRegs, []string{ - "ghcr.io/" + org + "/" + *pkg.Name, - tags[0], - }) - } - } - } - - if len(tableRegs) <= 1 { - logger.Info("No packages found") - return nil - } else { - pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() - } - return nil - -} From c917467384a4e7cd73aea64f9bf9c0eaccb4fa65 Mon Sep 17 00:00:00 2001 From: Catalin Date: Fri, 19 Apr 2024 17:15:13 +0300 Subject: [PATCH 4/6] moved github related code in github packages --- cmd/kndp/registry/search.go | 30 +++------------------ internal/{registry => github}/github.go | 35 ++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 30 deletions(-) rename internal/{registry => github}/github.go (58%) diff --git a/cmd/kndp/registry/search.go b/cmd/kndp/registry/search.go index 1ec9de7..d605e24 100644 --- a/cmd/kndp/registry/search.go +++ b/cmd/kndp/registry/search.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/charmbracelet/log" + "github.com/kndpio/kndp/internal/github" "github.com/kndpio/kndp/internal/registry" - "github.com/pterm/pterm" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -26,9 +26,7 @@ func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, confi logger.Error("Cannot get registries") return err } - tableRegs := pterm.TableData{ - {"URL", "VERSION"}, - } + for _, r := range registries { registryUrl := r.Annotations["kndp-registry-server-url"] u, _ := url.Parse(registryUrl) @@ -36,33 +34,13 @@ func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, confi // Switch statement to handle different registry types switch { case strings.Contains(registryUrl, "ghcr.io"): - pkgs, pkgVersions, err := registry.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) + _, _, err := github.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) if err != nil { return err } - for _, pkg := range pkgs { - if !strings.Contains(*pkg.Name, c.Query) { - continue - } - versions := pkgVersions[*pkg.Name] - for _, v := range versions { - tags := v.GetMetadata().Container.Tags - if len(tags) > 0 { - tableRegs = append(tableRegs, []string{ - "ghcr.io/" + org + "/" + *pkg.Name, - tags[0], - }) - } - } - } - if len(tableRegs) <= 1 { - logger.Info("No packages found") - } else { - pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() - } default: - _, _, err := registry.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) + _, _, err := github.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) if err != nil { return err } diff --git a/internal/registry/github.go b/internal/github/github.go similarity index 58% rename from internal/registry/github.go rename to internal/github/github.go index 10dcfc4..aa196e8 100644 --- a/internal/registry/github.go +++ b/internal/github/github.go @@ -1,20 +1,25 @@ -package registry +package github import ( "context" "encoding/json" + "strings" "github.com/charmbracelet/log" + "github.com/kndpio/kndp/internal/registry" + "github.com/pterm/pterm" "github.com/google/go-github/v61/github" ) // GetGithubPackages list packages and their versions from GitHub Container Registry -func GetGithubPackages(ctx context.Context, query string, version bool, r *Registry, registryUrl string, org string, logger *log.Logger) ([]*github.Package, map[string][]*github.PackageVersion, error) { - auth := RegistryConfig{} +func GetGithubPackages(ctx context.Context, query string, version bool, r *registry.Registry, registryUrl string, org string, logger *log.Logger) ([]*github.Package, map[string][]*github.PackageVersion, error) { + auth := registry.RegistryConfig{} json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) - + tableRegs := pterm.TableData{ + {"URL", "VERSION"}, + } pkgType := "container" pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) @@ -38,5 +43,27 @@ func GetGithubPackages(ctx context.Context, query string, version bool, r *Regis pkgVersions[*pkg.Name] = versions } } + + for _, pkg := range pkgs { + if !strings.Contains(*pkg.Name, query) { + continue + } + versions := pkgVersions[*pkg.Name] + for _, v := range versions { + tags := v.GetMetadata().Container.Tags + if len(tags) > 0 { + tableRegs = append(tableRegs, []string{ + "ghcr.io/" + org + "/" + *pkg.Name, + tags[0], + }) + } + } + } + if len(tableRegs) <= 1 { + logger.Info("No packages found") + } else { + pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() + } + return pkgs, pkgVersions, nil } From 181044ddd6248c419fb10d58a27fd5d5e06afe84 Mon Sep 17 00:00:00 2001 From: Catalin Date: Mon, 22 Apr 2024 15:05:03 +0300 Subject: [PATCH 5/6] moved search cmd to internal search package --- cmd/kndp/registry/search.go | 31 ++-------------------------- internal/search/search.go | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 29 deletions(-) create mode 100644 internal/search/search.go diff --git a/cmd/kndp/registry/search.go b/cmd/kndp/registry/search.go index d605e24..1ad5a7c 100644 --- a/cmd/kndp/registry/search.go +++ b/cmd/kndp/registry/search.go @@ -3,12 +3,8 @@ package registry import ( "context" - "net/url" - "strings" - "github.com/charmbracelet/log" - "github.com/kndpio/kndp/internal/github" - "github.com/kndpio/kndp/internal/registry" + "github.com/kndpio/kndp/internal/search" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -21,32 +17,9 @@ type SearchCmd struct { } func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, logger *log.Logger) error { - registries, err := registry.Registries(ctx, client) + err := search.SearchCmd(ctx, client, config, c.Query, c.Versions, logger) if err != nil { - logger.Error("Cannot get registries") return err } - - for _, r := range registries { - registryUrl := r.Annotations["kndp-registry-server-url"] - u, _ := url.Parse(registryUrl) - org := strings.TrimPrefix(u.Path, "/") - // Switch statement to handle different registry types - switch { - case strings.Contains(registryUrl, "ghcr.io"): - _, _, err := github.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) - if err != nil { - return err - } - - default: - _, _, err := github.GetGithubPackages(ctx, c.Query, c.Versions, r, registryUrl, org, logger) - if err != nil { - return err - } - } - - } - return nil } diff --git a/internal/search/search.go b/internal/search/search.go new file mode 100644 index 0000000..17f6e6b --- /dev/null +++ b/internal/search/search.go @@ -0,0 +1,41 @@ +package search + +import ( + "context" + "net/url" + "strings" + + "github.com/charmbracelet/log" + + "github.com/kndpio/kndp/internal/github" + "github.com/kndpio/kndp/internal/registry" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +func SearchCmd(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, query string, versions bool, logger *log.Logger) error { + registries, err := registry.Registries(ctx, client) + if err != nil { + logger.Error("Cannot get registries") + return err + } + + for _, r := range registries { + registryUrl := r.Annotations["kndp-registry-server-url"] + u, _ := url.Parse(registryUrl) + org := strings.TrimPrefix(u.Path, "/") + // Switch statement to handle different registry types + switch { + case strings.Contains(registryUrl, "ghcr.io"): + _, _, err := github.GetGithubPackages(ctx, query, versions, r, registryUrl, org, logger) + if err != nil { + return err + } + + default: + logger.Errorf("Registry %s is not supported", registryUrl) + } + + } + return nil +} From 815b7b81681c96b7c6f88931c20cedbdc71286c5 Mon Sep 17 00:00:00 2001 From: Catalin Date: Mon, 22 Apr 2024 15:33:41 +0300 Subject: [PATCH 6/6] unify getPackages func, move table usage in cmd level --- cmd/kndp/registry/search.go | 8 +++++++- internal/github/github.go | 15 +++++---------- internal/search/search.go | 13 +++++++------ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/cmd/kndp/registry/search.go b/cmd/kndp/registry/search.go index 1ad5a7c..14a3019 100644 --- a/cmd/kndp/registry/search.go +++ b/cmd/kndp/registry/search.go @@ -5,6 +5,7 @@ import ( "github.com/charmbracelet/log" "github.com/kndpio/kndp/internal/search" + "github.com/pterm/pterm" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -17,9 +18,14 @@ type SearchCmd struct { } func (c *SearchCmd) Run(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, logger *log.Logger) error { - err := search.SearchCmd(ctx, client, config, c.Query, c.Versions, logger) + tableRegs, err := search.SearchPackages(ctx, client, config, c.Query, c.Versions, logger) if err != nil { return err } + if len(tableRegs) <= 1 { + logger.Info("No packages found") + } else { + pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() + } return nil } diff --git a/internal/github/github.go b/internal/github/github.go index aa196e8..7aafada 100644 --- a/internal/github/github.go +++ b/internal/github/github.go @@ -12,8 +12,8 @@ import ( "github.com/google/go-github/v61/github" ) -// GetGithubPackages list packages and their versions from GitHub Container Registry -func GetGithubPackages(ctx context.Context, query string, version bool, r *registry.Registry, registryUrl string, org string, logger *log.Logger) ([]*github.Package, map[string][]*github.PackageVersion, error) { +// GetPackages list packages and their versions from Container Registry +func GetPackages(ctx context.Context, query string, version bool, r *registry.Registry, registryUrl string, org string, logger *log.Logger) (pterm.TableData, error) { auth := registry.RegistryConfig{} json.Unmarshal([]byte(r.Data[".dockerconfigjson"]), &auth) clientgh := github.NewClient(nil).WithAuthToken(auth.Auths[registryUrl].Password) @@ -25,7 +25,7 @@ func GetGithubPackages(ctx context.Context, query string, version bool, r *regis pkgs, _, err := clientgh.Organizations.ListPackages(ctx, org, &github.PackageListOptions{PackageType: &pkgType}) if err != nil { logger.Errorf("Cannot get packages from %s", registryUrl) - return nil, nil, err + return nil, err } pkgVersions := make(map[string][]*github.PackageVersion) @@ -33,7 +33,7 @@ func GetGithubPackages(ctx context.Context, query string, version bool, r *regis versions, _, err := clientgh.Organizations.PackageGetAllVersions(ctx, org, pkgType, pkg.GetName(), nil) if err != nil { logger.Errorf("Cannot get package versions for %s/%s", org, *pkg.Name) - return nil, nil, err + return nil, err } if !version { if len(versions) > 0 { @@ -59,11 +59,6 @@ func GetGithubPackages(ctx context.Context, query string, version bool, r *regis } } } - if len(tableRegs) <= 1 { - logger.Info("No packages found") - } else { - pterm.DefaultTable.WithHasHeader().WithData(tableRegs).Render() - } - return pkgs, pkgVersions, nil + return tableRegs, nil } diff --git a/internal/search/search.go b/internal/search/search.go index 17f6e6b..3388974 100644 --- a/internal/search/search.go +++ b/internal/search/search.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/charmbracelet/log" + "github.com/pterm/pterm" "github.com/kndpio/kndp/internal/github" "github.com/kndpio/kndp/internal/registry" @@ -13,11 +14,11 @@ import ( "k8s.io/client-go/rest" ) -func SearchCmd(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, query string, versions bool, logger *log.Logger) error { +func SearchPackages(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, query string, versions bool, logger *log.Logger) (pterm.TableData, error) { registries, err := registry.Registries(ctx, client) if err != nil { logger.Error("Cannot get registries") - return err + return nil, err } for _, r := range registries { @@ -27,15 +28,15 @@ func SearchCmd(ctx context.Context, client *kubernetes.Clientset, config *rest.C // Switch statement to handle different registry types switch { case strings.Contains(registryUrl, "ghcr.io"): - _, _, err := github.GetGithubPackages(ctx, query, versions, r, registryUrl, org, logger) + tableRegs, err := github.GetPackages(ctx, query, versions, r, registryUrl, org, logger) if err != nil { - return err + return nil, err } - + return tableRegs, nil default: logger.Errorf("Registry %s is not supported", registryUrl) } } - return nil + return nil, err }