From d0615920748b76db02dafd30a8b0bc3936ede09d Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Tue, 28 Oct 2025 11:52:41 -0400 Subject: [PATCH 01/11] clustercatalog content discovery for packages and bundle versions Signed-off-by: Ankita Thomas --- internal/cmd/internal/olmv1/printing.go | 2 ++ internal/pkg/v1/action/catalog_search.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/cmd/internal/olmv1/printing.go b/internal/cmd/internal/olmv1/printing.go index 18e4968..c1cc710 100644 --- a/internal/cmd/internal/olmv1/printing.go +++ b/internal/cmd/internal/olmv1/printing.go @@ -12,6 +12,8 @@ import ( "time" "github.com/blang/semver/v4" + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/property" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/util/json" diff --git a/internal/pkg/v1/action/catalog_search.go b/internal/pkg/v1/action/catalog_search.go index 0d4fc76..d5ca1ae 100644 --- a/internal/pkg/v1/action/catalog_search.go +++ b/internal/pkg/v1/action/catalog_search.go @@ -1,7 +1,7 @@ package action import ( - "context" + "contz" "fmt" "time" From 1c4b577ca5da12e41bc29b1b63bcc6baf2316de7 Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Mon, 10 Nov 2025 06:02:02 -0500 Subject: [PATCH 02/11] linter fixes Signed-off-by: Ankita Thomas --- internal/cmd/internal/olmv1/printing.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/cmd/internal/olmv1/printing.go b/internal/cmd/internal/olmv1/printing.go index c1cc710..18e4968 100644 --- a/internal/cmd/internal/olmv1/printing.go +++ b/internal/cmd/internal/olmv1/printing.go @@ -12,8 +12,6 @@ import ( "time" "github.com/blang/semver/v4" - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/property" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/util/json" From 388c2eae62e4a9d9be90cdba42e5a76ee997e88e Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Fri, 31 Oct 2025 03:25:12 -0400 Subject: [PATCH 03/11] reformat get commands Signed-off-by: Ankita Thomas --- go.mod | 4 ++ go.sum | 11 +++ ...atalog_installed_get.go => catalog_get.go} | 18 ++++- ...sion_installed_get.go => extension_get.go} | 12 +++- internal/cmd/internal/olmv1/flags.go | 16 +++++ internal/cmd/internal/olmv1/printing.go | 67 ++++++++++++++++++- ...atalog_installed_get.go => catalog_get.go} | 13 ++-- ...talled_get_test.go => catalog_get_test.go} | 0 ...sion_installed_get.go => extension_get.go} | 8 ++- ...lled_get_test.go => extension_get_test.go} | 0 10 files changed, 135 insertions(+), 14 deletions(-) rename internal/cmd/internal/olmv1/{catalog_installed_get.go => catalog_get.go} (65%) rename internal/cmd/internal/olmv1/{extension_installed_get.go => extension_get.go} (72%) create mode 100644 internal/cmd/internal/olmv1/flags.go rename internal/pkg/v1/action/{catalog_installed_get.go => catalog_get.go} (76%) rename internal/pkg/v1/action/{catalog_installed_get_test.go => catalog_get_test.go} (100%) rename internal/pkg/v1/action/{extension_installed_get.go => extension_get.go} (82%) rename internal/pkg/v1/action/{extension_installed_get_test.go => extension_get_test.go} (100%) diff --git a/go.mod b/go.mod index 9f4da0d..94022eb 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( k8s.io/api v0.32.2 k8s.io/apiextensions-apiserver v0.32.2 k8s.io/apimachinery v0.32.2 + k8s.io/cli-runtime v0.32.2 k8s.io/client-go v0.32.2 sigs.k8s.io/controller-runtime v0.20.2 sigs.k8s.io/yaml v1.4.0 @@ -27,6 +28,7 @@ require ( require ( cel.dev/expr v0.18.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/hcsshim v0.12.9 // indirect @@ -83,6 +85,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.0 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.5.0 // indirect @@ -91,6 +94,7 @@ require ( github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/user v0.3.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect diff --git a/go.sum b/go.sum index bf102d4..14bfc4c 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= @@ -62,6 +64,8 @@ github.com/containers/storage v1.56.1/go.mod h1:c6WKowcAlED/DkWGNuL9bvGYqIWCVy7i github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -212,6 +216,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= @@ -230,6 +236,8 @@ github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -424,6 +432,7 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -512,6 +521,8 @@ k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw= k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM= +k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks= +k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8= k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= diff --git a/internal/cmd/internal/olmv1/catalog_installed_get.go b/internal/cmd/internal/olmv1/catalog_get.go similarity index 65% rename from internal/cmd/internal/olmv1/catalog_installed_get.go rename to internal/cmd/internal/olmv1/catalog_get.go index 87eb5dd..eb585ca 100644 --- a/internal/cmd/internal/olmv1/catalog_installed_get.go +++ b/internal/cmd/internal/olmv1/catalog_get.go @@ -6,6 +6,7 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + "k8s.io/apimachinery/pkg/labels" ) // NewCatalogInstalledGetCmd handles get commands in the form of: @@ -15,6 +16,7 @@ import ( func NewCatalogInstalledGetCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogInstalledGet(cfg) i.Logf = log.Printf + catalogGetOptions := getOptions{} cmd := &cobra.Command{ Use: "catalog [catalog_name]", @@ -25,14 +27,26 @@ func NewCatalogInstalledGetCmd(cfg *action.Configuration) *cobra.Command { if len(args) == 1 { i.CatalogName = args[0] } + var err error + switch catalogGetOptions.Output { + case "yaml", "json", "": + default: + log.Fatalf("unrecognized output format %s", catalogGetOptions.Output) + } + if len(catalogGetOptions.Selector) > 0 { + i.Selector, err = labels.Parse(catalogGetOptions.Selector) + if err != nil { + log.Fatalf("unable to parse selector %s: %v", catalogGetOptions.Selector, err) + } + } installedCatalogs, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed getting installed catalog(s): %v", err) } - - printFormattedCatalogs(installedCatalogs...) + printFormattedCatalogs(catalogGetOptions.Output, installedCatalogs...) }, } + bindGetFlags(cmd.Flags(), &catalogGetOptions) return cmd } diff --git a/internal/cmd/internal/olmv1/extension_installed_get.go b/internal/cmd/internal/olmv1/extension_get.go similarity index 72% rename from internal/cmd/internal/olmv1/extension_installed_get.go rename to internal/cmd/internal/olmv1/extension_get.go index b85a93b..2efdbf1 100644 --- a/internal/cmd/internal/olmv1/extension_installed_get.go +++ b/internal/cmd/internal/olmv1/extension_get.go @@ -6,6 +6,7 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + "k8s.io/apimachinery/pkg/labels" ) // NewExtensionInstalledGetCmd handles get commands in the form of: @@ -15,6 +16,7 @@ import ( func NewExtensionInstalledGetCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionInstalledGet(cfg) i.Logf = log.Printf + extensionGetOptions := getOptions{} cmd := &cobra.Command{ Use: "extension [extension_name]", @@ -25,14 +27,22 @@ func NewExtensionInstalledGetCmd(cfg *action.Configuration) *cobra.Command { if len(args) == 1 { i.ExtensionName = args[0] } + var err error + if len(extensionGetOptions.Selector) > 0 { + i.Selector, err = labels.Parse(extensionGetOptions.Selector) + if err != nil { + log.Fatalf("unable to parse selector %s: %v", extensionGetOptions.Selector, err) + } + } installedExtensions, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed getting installed extension(s): %v", err) } - printFormattedExtensions(installedExtensions...) + printFormattedExtensions(extensionGetOptions.Output, installedExtensions...) }, } + bindGetFlags(cmd.Flags(), &extensionGetOptions) return cmd } diff --git a/internal/cmd/internal/olmv1/flags.go b/internal/cmd/internal/olmv1/flags.go new file mode 100644 index 0000000..c9ff4e1 --- /dev/null +++ b/internal/cmd/internal/olmv1/flags.go @@ -0,0 +1,16 @@ +package olmv1 + +import "github.com/spf13/pflag" + +type getOptions struct { + Output string + Selector string +} + +func bindGetFlags(fs *pflag.FlagSet, o *getOptions) { + fs.StringVarP(&o.Output, "output", "o", "", "Output format. One of: (json, yaml)") + fs.StringVarP(&o.Selector, "selector", "l", "", "Selector (label query) to filter on, "+ + "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ + "in (value3)). Matching objects must satisfy all of the specified label constraints.") + +} diff --git a/internal/cmd/internal/olmv1/printing.go b/internal/cmd/internal/olmv1/printing.go index 18e4968..58b9005 100644 --- a/internal/cmd/internal/olmv1/printing.go +++ b/internal/cmd/internal/olmv1/printing.go @@ -15,13 +15,45 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/util/json" + "k8s.io/cli-runtime/pkg/printers" olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/operator-registry/alpha/declcfg" "github.com/operator-framework/operator-registry/alpha/property" ) -func printFormattedExtensions(extensions ...olmv1.ClusterExtension) { +func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterExtension) { + if len(extensions) == 0 { + fmt.Println("No resources found") + return + } + switch outputFormat { + case "yaml": + printer := printers.YAMLPrinter{} + if len(extensions) > 1 { + if err := printer.PrintObj(&olmv1.ClusterExtensionList{Items: extensions}, os.Stdout); err != nil { + fmt.Printf("failed to marshal response to YAML: %v\n", err) + } + return + } + if err := printer.PrintObj(&extensions[0], os.Stdout); err != nil { + fmt.Printf("failed to marshal response to YAML: %v\n", err) + } + return + case "json": + printer := printers.JSONPrinter{} + if len(extensions) > 1 { + if err := printer.PrintObj(&olmv1.ClusterExtensionList{Items: extensions}, os.Stdout); err != nil { + fmt.Printf("failed to marshal response to JSON: %v\n", err) + } + return + } + if err := printer.PrintObj(&extensions[0], os.Stdout); err != nil { + fmt.Printf("failed to marshal response to JSON: %v\n", err) + } + return + default: + } tw := tabwriter.NewWriter(os.Stdout, 3, 4, 2, ' ', 0) _, _ = fmt.Fprint(tw, "NAME\tINSTALLED BUNDLE\tVERSION\tSOURCE TYPE\tINSTALLED\tPROGRESSING\tAGE\n") @@ -46,7 +78,38 @@ func printFormattedExtensions(extensions ...olmv1.ClusterExtension) { _ = tw.Flush() } -func printFormattedCatalogs(catalogs ...olmv1.ClusterCatalog) { +func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalog) { + if len(catalogs) == 0 { + fmt.Println("No resources found") + return + } + switch outputFormat { + case "yaml": + printer := printers.YAMLPrinter{} + if len(catalogs) > 1 { + if err := printer.PrintObj(&olmv1.ClusterCatalogList{Items: catalogs}, os.Stdout); err != nil { + fmt.Printf("failed to marshal response to YAML: %v\n", err) + } + return + } + if err := printer.PrintObj(&catalogs[0], os.Stdout); err != nil { + fmt.Printf("failed to marshal response to YAML: %v\n", err) + } + return + case "json": + printer := printers.JSONPrinter{} + if len(catalogs) > 1 { + if err := printer.PrintObj(&olmv1.ClusterCatalogList{Items: catalogs}, os.Stdout); err != nil { + fmt.Printf("failed to marshal response to JSON: %v\n", err) + } + return + } + if err := printer.PrintObj(&catalogs[0], os.Stdout); err != nil { + fmt.Printf("failed to marshal response to JSON: %v\n", err) + } + return + default: + } tw := tabwriter.NewWriter(os.Stdout, 3, 4, 2, ' ', 0) _, _ = fmt.Fprint(tw, "NAME\tAVAILABILITY\tPRIORITY\tLASTUNPACKED\tSERVING\tAGE\n") diff --git a/internal/pkg/v1/action/catalog_installed_get.go b/internal/pkg/v1/action/catalog_get.go similarity index 76% rename from internal/pkg/v1/action/catalog_installed_get.go rename to internal/pkg/v1/action/catalog_get.go index 2a27a39..c3c243f 100644 --- a/internal/pkg/v1/action/catalog_installed_get.go +++ b/internal/pkg/v1/action/catalog_get.go @@ -16,6 +16,7 @@ import ( type CatalogInstalledGet struct { config *action.Configuration CatalogName string + Selector labels.Selector Selector string @@ -45,15 +46,11 @@ func (i *CatalogInstalledGet) Run(ctx context.Context) ([]olmv1.ClusterCatalog, // list var result olmv1.ClusterCatalogList - listOptions := &client.ListOptions{} - if len(i.Selector) > 0 { - labelSelector, err := labels.Parse(i.Selector) - if err != nil { - return nil, fmt.Errorf("unable to parse selector %s: %v", i.Selector, err) - } - listOptions.LabelSelector = labelSelector + listOpts := &client.ListOptions{} + if i.Selector != nil { + listOpts.LabelSelector = i.Selector } - err := i.config.Client.List(ctx, &result, listOptions) + err := i.config.Client.List(ctx, &result, listOpts) return result.Items, err } diff --git a/internal/pkg/v1/action/catalog_installed_get_test.go b/internal/pkg/v1/action/catalog_get_test.go similarity index 100% rename from internal/pkg/v1/action/catalog_installed_get_test.go rename to internal/pkg/v1/action/catalog_get_test.go diff --git a/internal/pkg/v1/action/extension_installed_get.go b/internal/pkg/v1/action/extension_get.go similarity index 82% rename from internal/pkg/v1/action/extension_installed_get.go rename to internal/pkg/v1/action/extension_get.go index 994fc5f..c52407c 100644 --- a/internal/pkg/v1/action/extension_installed_get.go +++ b/internal/pkg/v1/action/extension_get.go @@ -3,6 +3,7 @@ package action import ( "context" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -14,6 +15,7 @@ import ( type ExtensionInstalledGet struct { config *action.Configuration ExtensionName string + Selector labels.Selector Logf func(string, ...interface{}) } @@ -40,7 +42,11 @@ func (i *ExtensionInstalledGet) Run(ctx context.Context) ([]olmv1.ClusterExtensi // list var result olmv1.ClusterExtensionList - err := i.config.Client.List(ctx, &result, &client.ListOptions{}) + listOpts := &client.ListOptions{} + if i.Selector != nil { + listOpts.LabelSelector = i.Selector + } + err := i.config.Client.List(ctx, &result, listOpts) return result.Items, err } diff --git a/internal/pkg/v1/action/extension_installed_get_test.go b/internal/pkg/v1/action/extension_get_test.go similarity index 100% rename from internal/pkg/v1/action/extension_installed_get_test.go rename to internal/pkg/v1/action/extension_get_test.go From aaf1e45abf4ee84187f565ec075d051c16b5183e Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Fri, 31 Oct 2025 09:11:00 -0400 Subject: [PATCH 04/11] reformat install commands Signed-off-by: Ankita Thomas --- go.mod | 147 ++--- go.sum | 538 ++++++++++-------- internal/cmd/internal/olmv1/catalog_create.go | 31 +- .../cmd/internal/olmv1/extension_install.go | 66 ++- internal/pkg/v1/action/catalog_create.go | 19 +- internal/pkg/v1/action/catalog_create_test.go | 6 +- internal/pkg/v1/action/extension_install.go | 58 +- internal/pkg/v1/action/helpers.go | 1 + 8 files changed, 512 insertions(+), 354 deletions(-) diff --git a/go.mod b/go.mod index 94022eb..23acf44 100644 --- a/go.mod +++ b/go.mod @@ -1,82 +1,80 @@ module github.com/operator-framework/kubectl-operator -go 1.23.4 +go 1.24.4 require ( github.com/blang/semver/v4 v4.0.0 - github.com/containerd/containerd v1.7.26 + github.com/containerd/containerd v1.7.28 github.com/containerd/platforms v0.2.1 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.36.2 + github.com/onsi/gomega v1.38.2 github.com/opencontainers/image-spec v1.1.1 - github.com/operator-framework/api v0.30.0 - github.com/operator-framework/operator-controller v1.2.0 + github.com/operator-framework/api v0.34.0 + github.com/operator-framework/operator-controller v1.5.1 github.com/operator-framework/operator-lifecycle-manager v0.23.1 - github.com/operator-framework/operator-registry v1.50.0 + github.com/operator-framework/operator-registry v1.57.0 github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.9.1 - github.com/spf13/pflag v1.0.6 - k8s.io/api v0.32.2 - k8s.io/apiextensions-apiserver v0.32.2 - k8s.io/apimachinery v0.32.2 - k8s.io/cli-runtime v0.32.2 - k8s.io/client-go v0.32.2 - sigs.k8s.io/controller-runtime v0.20.2 - sigs.k8s.io/yaml v1.4.0 + github.com/spf13/cobra v1.10.1 + github.com/spf13/pflag v1.0.9 + k8s.io/api v0.33.4 + k8s.io/apiextensions-apiserver v0.33.4 + k8s.io/apimachinery v0.33.4 + k8s.io/cli-runtime v0.33.3 + k8s.io/client-go v0.33.4 + sigs.k8s.io/controller-runtime v0.21.0 + sigs.k8s.io/yaml v1.6.0 ) require ( - cel.dev/expr v0.18.0 // indirect - github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect + cel.dev/expr v0.24.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + github.com/BurntSushi/toml v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.12.9 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/containerd/cgroups/v3 v3.0.3 // indirect - github.com/containerd/containerd/api v1.8.0 // indirect - github.com/containerd/continuity v0.4.4 // indirect - github.com/containerd/errdefs v0.3.0 // indirect + github.com/Microsoft/hcsshim v0.13.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect + github.com/containerd/cgroups/v3 v3.0.5 // indirect + github.com/containerd/containerd/api v1.9.0 // indirect + github.com/containerd/continuity v0.4.5 // indirect + github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/ttrpc v1.2.7 // indirect - github.com/containerd/typeurl/v2 v2.2.0 // indirect - github.com/containers/common v0.61.0 // indirect - github.com/containers/image/v5 v5.33.1 // indirect + github.com/containerd/typeurl/v2 v2.2.3 // indirect + github.com/containers/common v0.64.1 // indirect + github.com/containers/image/v5 v5.36.2 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect - github.com/containers/ocicrypt v1.2.0 // indirect - github.com/containers/storage v1.56.1 // indirect + github.com/containers/ocicrypt v1.2.1 // indirect + github.com/containers/storage v1.59.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/cli v27.5.0+incompatible // indirect + github.com/docker/cli v28.3.3+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v27.5.0+incompatible // indirect - github.com/docker/docker-credential-helpers v0.8.2 // indirect + github.com/docker/docker v28.3.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.8.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.8.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.6.1 // indirect - github.com/go-git/go-git/v5 v5.13.1 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-git/go-billy/v5 v5.6.2 // indirect + github.com/go-git/go-git/v5 v5.16.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/swag v0.23.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.22.1 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/google/cel-go v0.26.0 // indirect github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/h2non/filetype v1.1.3 // indirect github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -89,50 +87,53 @@ require ( github.com/mailru/easyjson v0.9.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.5.0 // indirect - github.com/moby/sys/capability v0.3.0 // indirect + github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect - github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/user v0.3.0 // indirect + github.com/moby/sys/sequential v0.6.0 // indirect + github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect - github.com/moby/term v0.5.0 // indirect + github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/runtime-spec v1.2.0 // indirect + github.com/opencontainers/runtime-spec v1.2.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/stoewer/go-strcase v1.3.1 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/bbolt v1.3.11 // indirect + go.etcd.io/bbolt v1.4.3 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect - go.opentelemetry.io/otel v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - go.opentelemetry.io/otel/trace v1.33.0 // indirect - golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.29.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/time v0.10.0 // indirect - google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect - google.golang.org/grpc v1.68.1 // indirect - google.golang.org/protobuf v1.36.5 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/term v0.34.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/time v0.12.0 // indirect + google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect - k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect + k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a // indirect + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect ) diff --git a/go.sum b/go.sum index 14bfc4c..2341021 100644 --- a/go.sum +++ b/go.sum @@ -1,46 +1,48 @@ -cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= -cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= -github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA= +github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok= +github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= +github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= -github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/containerd v1.7.26 h1:3cs8K2RHlMQaPifLqgRyI4VBkoldNdEw62cb7qQga7k= -github.com/containerd/containerd v1.7.26/go.mod h1:m4JU0E+h0ebbo9yXD7Hyt+sWnc8tChm7MudCjj4jRvQ= -github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0= -github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= -github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII= -github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= -github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4= -github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= +github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= +github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c= +github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs= +github.com/containerd/containerd/api v1.9.0 h1:HZ/licowTRazus+wt9fM6r/9BQO7S0vD5lMcWspGIg0= +github.com/containerd/containerd/api v1.9.0/go.mod h1:GhghKFmTR3hNtyznBoQ0EMWr9ju5AqHjcZPsSpTKutI= +github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= +github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -49,23 +51,23 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ= github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= -github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= -github.com/containers/common v0.61.0 h1:j/84PTqZIKKYy42OEJsZmjZ4g4Kq2ERuC3tqp2yWdh4= -github.com/containers/common v0.61.0/go.mod h1:NGRISq2vTFPSbhNqj6MLwyes4tWSlCnqbJg7R77B8xc= -github.com/containers/image/v5 v5.33.1 h1:nTWKwxAlY0aJrilvvhssqssJVnley6VqxkLiLzTEYIs= -github.com/containers/image/v5 v5.33.1/go.mod h1:/FJiLlvVbeBxWNMPVPPIWJxHTAzwBoFvyN0a51zo1CE= +github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= +github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= +github.com/containers/common v0.64.1 h1:E8vSiL+B84/UCsyVSb70GoxY9cu+0bseLujm4EKF6GE= +github.com/containers/common v0.64.1/go.mod h1:CtfQNHoCAZqWeXMwdShcsxmMJSeGRgKKMqAwRKmWrHE= +github.com/containers/image/v5 v5.36.2 h1:GcxYQyAHRF/pLqR4p4RpvKllnNL8mOBn0eZnqJbfTwk= +github.com/containers/image/v5 v5.36.2/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= -github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM= -github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U= -github.com/containers/storage v1.56.1 h1:gDZj/S6Zxus4Xx42X6iNB3ODXuh0qoOdH/BABfrvcKo= -github.com/containers/storage v1.56.1/go.mod h1:c6WKowcAlED/DkWGNuL9bvGYqIWCVy7isRMdCSKWNjk= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM= +github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ= +github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs= +github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= +github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -73,28 +75,28 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/distribution v2.7.1+incompatible h1:aGFx4EvJWKEh//lHPLwFhFgwFHKH06TzNVPamrMn04M= -github.com/distribution/distribution/v3 v3.0.0-rc.1 h1:6M4ewmPBUhF7wtQ8URLOQ1W/PQuVKiD1u8ymwLDUGqQ= -github.com/distribution/distribution/v3 v3.0.0-rc.1/go.mod h1:tFjaPDeHCrLg28e4feBIy27cP+qmrc/mvkl6MFIfVi4= +github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= +github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.5.0+incompatible h1:aMphQkcGtpHixwwhAXJT1rrK/detk2JIvDaFkLctbGM= -github.com/docker/cli v27.5.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo= +github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.5.0+incompatible h1:um++2NcQtGRTz5eEgO6aJimo6/JxrTXC941hd05JO6U= -github.com/docker/docker v27.5.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= -github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= +github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= +github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= +github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32 h1:EHZfspsnLAz8Hzccd67D5abwLiqoqym2jz/jOS39mCk= +github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= -github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -105,41 +107,43 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= +github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= -github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= -github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= -github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= +github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM= +github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y= -github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks= +github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4B/swMiAmDLs= +github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -153,8 +157,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40= -github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= +github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= +github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -166,11 +170,11 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU= +github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y= 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= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -178,23 +182,21 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0 h1:+epNPbD5EqgpEMm5wrl4Hqts3jZt8+kYaqUisuuIGTk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c h1:fEE5/5VNnYUoBOj2I9TP8Jc+a7lge3QWn9DKE7NCwfc= github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= -github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= -github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= -github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= +github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5AmgmWNH1g+oFFVUHOEc= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -216,28 +218,34 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/letsencrypt/boulder v0.0.0-20250624003606-5ddd5acf990d h1:fCRb9hXR4QQJpwc7xnGugnva0DD5ollTGkys0n8aXT4= +github.com/letsencrypt/boulder v0.0.0-20250624003606-5ddd5acf990d/go.mod h1:BVoSL2Ed8oCncct0meeBqoTY7b1Mzx7WqEOZ8EisFmY= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= -github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= +github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= -github.com/moby/sys/capability v0.3.0 h1:kEP+y6te0gEXIaeQhIi0s7vKs/w0RPoH1qPa6jROcVg= -github.com/moby/sys/capability v0.3.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= +github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= +github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= +github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -254,151 +262,181 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= -github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/ginkgo/v2 v2.25.2 h1:hepmgwx1D+llZleKQDMEvy8vIlCxMGt7W5ZxDjIEhsw= +github.com/onsi/ginkgo/v2 v2.25.2/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= -github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/operator-framework/api v0.30.0 h1:44hCmGnEnZk/Miol5o44dhSldNH0EToQUG7vZTl29kk= -github.com/operator-framework/api v0.30.0/go.mod h1:FYxAPhjtlXSAty/fbn5YJnFagt6SpJZJgFNNbvDe5W0= -github.com/operator-framework/operator-controller v1.2.0 h1:5fn41pZuJ41jHUwWSts8igDN/IXILeLyqRKnMpN4S8I= -github.com/operator-framework/operator-controller v1.2.0/go.mod h1:lDudFGy4YtcMFcUDYLet3mUA/Wzq6pTVrLTBWOZLp/Q= +github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= +github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/operator-framework/api v0.34.0 h1:REiEaYhG1CWmDoajdcAdZqtgoljWG+ixMY59vUX5pFI= +github.com/operator-framework/api v0.34.0/go.mod h1:eGncUNIYvWtfGCCKmLzGXvoi3P0TDf3Yd/Z0Sn9E6SQ= +github.com/operator-framework/operator-controller v1.5.1 h1:J3xdRHzh9ajuKt/i1fWxoOLUf3kMpaOnGf1XNZ6+Klg= +github.com/operator-framework/operator-controller v1.5.1/go.mod h1:6BpO9yzrmr1s7zqnk7YUA9SJlNVD+gA25JS5sg6axCE= github.com/operator-framework/operator-lifecycle-manager v0.23.1 h1:Xw2ml1T4W2ieoFaVwanW/eFlZ11yAOJZUpUI8RLSql8= github.com/operator-framework/operator-lifecycle-manager v0.23.1/go.mod h1:q/QgVi/WooEyOFw8ipQrb2A/InjM4djCwPf7IlCpSOQ= -github.com/operator-framework/operator-registry v1.50.0 h1:kMAwsKAEDjuSx5dGchMX+CD3SMHWwOAC/xyK3LQweB4= -github.com/operator-framework/operator-registry v1.50.0/go.mod h1:713Z/XzA5jViFMGIsXmfAcpA6h5uUKqUl3fO1t4taa0= -github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= -github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= -github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= -github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/operator-framework/operator-registry v1.57.0 h1:mQ4c8A8VUxZPJ0QCFRNio+7JEsLX6eKxlDSl6ORCRdk= +github.com/operator-framework/operator-registry v1.57.0/go.mod h1:9rAZH/LZ/ttEuTvL1D4KApGqOtRDE6fJzzOrJNcBu7g= +github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= +github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I= +github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= +github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= -github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M= +github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= +github.com/prometheus/client_golang v1.23.1 h1:w6gXMLQGgd0jXXlote9lRHMe0nG01EbnJT+C0EJru2Y= +github.com/prometheus/client_golang v1.23.1/go.mod h1:br8j//v2eg2K5Vvna5klK8Ku5pcU5r4ll73v6ik5dIQ= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= -github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U= -github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= -github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ= -github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= -github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.0 h1:K/rJPHrG3+AoQs50r2+0t7zMnMzek2Vbv31OFVsMeVY= +github.com/prometheus/common v0.66.0/go.mod h1:Ux6NtV1B4LatamKE63tJBntoxD++xmtI/lK0VtEplN4= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0 h1:uTiEyEyfLhkw678n6EulHVto8AkcXVr8zUcBJNZ0ark= +github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0/go.mod h1:eFYL/99JvdLP4T9/3FZ5t2pClnv7mMskc+WstTcyVr4= +github.com/redis/go-redis/extra/redisotel/v9 v9.10.0 h1:4z7/hCJ9Jft8EBb2tDmK38p2WjyIEJ1ShhhwAhjOCps= +github.com/redis/go-redis/extra/redisotel/v9 v9.10.0/go.mod h1:B0thqLh4hB8MvvcUKSwyP5YiIcCCp8UrQ0cA9gEqyjk= +github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs= +github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc= +github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw= +github.com/sigstore/fulcio v1.7.1 h1:RcoW20Nz49IGeZyu3y9QYhyyV3ZKQ85T+FXPKkvE+aQ= +github.com/sigstore/fulcio v1.7.1/go.mod h1:7lYY+hsd8Dt+IvKQRC+KEhWpCZ/GlmNvwIa5JhypMS8= +github.com/sigstore/protobuf-specs v0.4.3 h1:kRgJ+ciznipH9xhrkAbAEHuuxD3GhYnGC873gZpjJT4= +github.com/sigstore/protobuf-specs v0.4.3/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= +github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU= +github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= +github.com/smallstep/pkcs7 v0.2.1 h1:6Kfzr/QizdIuB6LSv8y1LJdZ3aPSfTNhTLqAx9CTLfA= +github.com/smallstep/pkcs7 v0.2.1/go.mod h1:RcXHsMfL+BzH8tRhmrF1NkkpebKpq3JEM66cOFxanf0= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= +github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= +github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs= +github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= -github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= -github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= +github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= +github.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg= +github.com/ulikunitz/xz v0.5.14/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= +github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +github.com/vbauerster/mpb/v8 v8.10.2 h1:2uBykSHAYHekE11YvJhKxYmLATKHAGorZwFlyNw4hHM= +github.com/vbauerster/mpb/v8 v8.10.2/go.mod h1:+Ja4P92E3/CorSZgfDtK46D7AVbDqmBQRTmyTqPElo0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= -go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= +go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib v1.3.0 h1:p9Gd+3dD7yB+AIph2Ltg11QDX6Y+yWMH0YQVTpTTP2c= -go.opentelemetry.io/contrib/bridges/prometheus v0.54.0 h1:WWL67oxtknNVMb70lJXxXruf8UyK/a9hmIE1XO3Uedg= -go.opentelemetry.io/contrib/bridges/prometheus v0.54.0/go.mod h1:LqNcnXmyULp8ertk4hUTVtSUvKXj4h1Mx7gUCSSr/q0= -go.opentelemetry.io/contrib/exporters/autoexport v0.54.0 h1:dTmcmVm4J54IRPGm5oVjLci1uYat4UDea84E2tyBaAk= -go.opentelemetry.io/contrib/exporters/autoexport v0.54.0/go.mod h1:zPp5Fwpq2Hc7xMtVttg6GhZMcfTESjVbY9ONw2o/Dc4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 h1:RyrtJzu5MAmIcbRrwg75b+w3RlZCP0vJByDVzcpAe3M= +go.opentelemetry.io/contrib/bridges/prometheus v0.61.0/go.mod h1:tirr4p9NXbzjlbruiRGp53IzlYrDk5CO2fdHj0sSSaY= +go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= +go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 h1:4d++HQ+Ihdl+53zSjtsCUFDmNMju2FC9qFkUlTxPLqo= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0/go.mod h1:mQX5dTO3Mh5ZF7bPKDkt5c/7C41u/SiDr9XgTpzXXn8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0/go.mod h1:t4BrYLHU450Zo9fnydWlIuswB1bm7rM8havDpWOJeDo= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 h1:xvhQxJ/C9+RTnAj5DpTg7LSM1vbbMTiXt7e9hsfqHNw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0/go.mod h1:Fcvs2Bz1jkDM+Wf5/ozBGmi3tQ/c9zPKLnsipnfhGAo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= -go.opentelemetry.io/otel/exporters/prometheus v0.51.0 h1:G7uexXb/K3T+T9fNLCCKncweEtNEBMTO+46hKX5EdKw= -go.opentelemetry.io/otel/exporters/prometheus v0.51.0/go.mod h1:v0mFe5Kk7woIh938mrZBJBmENYquyA0IICrlYm4Y0t4= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0 h1:ThVXnEsdwNcxdBO+r96ci1xbF+PgNjwlk457VNuJODo= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0/go.mod h1:rHWcSmC4q2h3gje/yOq6sAOaq8+UHxN/Ru3BbmDXOfY= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 h1:X3ZjNp36/WlkSYx0ul2jw4PtbNEDDeLskw3VPsrpYM0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0/go.mod h1:2uL/xnOXh0CHOBFCWXz5u1A4GXLiW+0IQIzVbeOEQ0U= -go.opentelemetry.io/otel/log v0.5.0 h1:x1Pr6Y3gnXgl1iFBwtGy1W/mnzENoK0w0ZoaeOI3i30= -go.opentelemetry.io/otel/log v0.5.0/go.mod h1:NU/ozXeGuOR5/mjCRXYbTC00NFJ3NYuraV/7O78F0rE= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/sdk/log v0.5.0 h1:A+9lSjlZGxkQOr7QSBJcuyyYBw79CufQ69saiJLey7o= -go.opentelemetry.io/otel/sdk/log v0.5.0/go.mod h1:zjxIW7sw1IHolZL2KlSAtrUi8JHttoeiQy43Yl3WuVQ= -go.opentelemetry.io/otel/sdk/metric v1.29.0 h1:K2CfmJohnRgvZ9UAj2/FhIf/okdWcNdBwe1m8xFXiSY= -go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 h1:zwdo1gS2eH26Rg+CoqVQpEK1h8gvt5qyU5Kk5Bixvow= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0/go.mod h1:rUKCPscaRWWcqGT6HnEmYrK+YNe5+Sw64xgQTOJ5b30= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= +go.opentelemetry.io/otel/exporters/prometheus v0.58.0 h1:CJAxWKFIqdBennqxJyOgnt5LqkeFRT+Mz3Yjz3hL+h8= +go.opentelemetry.io/otel/exporters/prometheus v0.58.0/go.mod h1:7qo/4CLI+zYSNbv0GMNquzuss2FVZo3OYrGh96n4HNc= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2/go.mod h1:ZccPZoPOoq8x3Trik/fCsba7DEYDUnN6yX79pgp2BUQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 h1:G8Xec/SgZQricwWBJF/mHZc7A02YHedfFDENwJEdRA0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= +go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= +go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= +go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= +go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 h1:aWwlzYV971S4BXRS9AmqwDLAD85ouC6X+pocatKY58c= -golang.org/x/exp v0.0.0-20250228200357-dead58393ab7/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -410,18 +448,18 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -434,16 +472,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -453,30 +491,32 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU= -google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= +google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= +google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU= +google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= -google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -486,8 +526,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -508,38 +548,44 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= -k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= -k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= -k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA= -k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= -k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw= -k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM= -k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks= -k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8= -k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= -k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= -k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= -k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0= +k8s.io/api v0.33.4 h1:oTzrFVNPXBjMu0IlpA2eDDIU49jsuEorGHB4cvKupkk= +k8s.io/api v0.33.4/go.mod h1:VHQZ4cuxQ9sCUMESJV5+Fe8bGnqAARZ08tSTdHWfeAc= +k8s.io/apiextensions-apiserver v0.33.4 h1:rtq5SeXiDbXmSwxsF0MLe2Mtv3SwprA6wp+5qh/CrOU= +k8s.io/apiextensions-apiserver v0.33.4/go.mod h1:mWXcZQkQV1GQyxeIjYApuqsn/081hhXPZwZ2URuJeSs= +k8s.io/apimachinery v0.33.4 h1:SOf/JW33TP0eppJMkIgQ+L6atlDiP/090oaX0y9pd9s= +k8s.io/apimachinery v0.33.4/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/apiserver v0.33.4 h1:6N0TEVA6kASUS3owYDIFJjUH6lgN8ogQmzZvaFFj1/Y= +k8s.io/apiserver v0.33.4/go.mod h1:8ODgXMnOoSPLMUg1aAzMFx+7wTJM+URil+INjbTZCok= +k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA= +k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo= +k8s.io/client-go v0.33.4 h1:TNH+CSu8EmXfitntjUPwaKVPN0AYMbc9F1bBS8/ABpw= +k8s.io/client-go v0.33.4/go.mod h1:LsA0+hBG2DPwovjd931L/AoaezMPX9CmBgyVyBZmbCY= +k8s.io/component-base v0.33.4 h1:Jvb/aw/tl3pfgnJ0E0qPuYLT0NwdYs1VXXYQmSuxJGY= +k8s.io/component-base v0.33.4/go.mod h1:567TeSdixWW2Xb1yYUQ7qk5Docp2kNznKL87eygY8Rc= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= -k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= -k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= -k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc= -sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= +k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a h1:ZV3Zr+/7s7aVbjNGICQt+ppKWsF1tehxggNfbM7XnG8= +k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg= +oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= +oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= +sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= -sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI= +sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/internal/cmd/internal/olmv1/catalog_create.go b/internal/cmd/internal/olmv1/catalog_create.go index df76c87..294916e 100644 --- a/internal/cmd/internal/olmv1/catalog_create.go +++ b/internal/cmd/internal/olmv1/catalog_create.go @@ -9,6 +9,9 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewCatalogCreateCmd allows creating a new catalog @@ -24,11 +27,26 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { i.CatalogName = args[0] i.ImageSourceRef = args[1] + if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { + log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + } - if err := i.Run(cmd.Context()); err != nil { - log.Fatalf("failed to create catalog %q: %v", i.CatalogName, err) + catalogObj, err := i.Run(cmd.Context()) + if err != nil { + log.Fatalf("failed to create catalog %q: %v\n", i.CatalogName, err) + } + if len(i.DryRun) == 0 { + log.Printf("catalog %q created\n", i.CatalogName) + return } - log.Printf("catalog %q created", i.CatalogName) + if len(i.Output) == 0 { + log.Printf("catalog %q created (dry run)\n", i.CatalogName) + return + } + + catalogObj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + printFormattedCatalogs(i.Output, *catalogObj) }, } bindCatalogCreateFlags(cmd.Flags(), i) @@ -38,8 +56,11 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { func bindCatalogCreateFlags(fs *pflag.FlagSet, i *v1action.CatalogCreate) { fs.Int32Var(&i.Priority, "priority", 0, "priority determines the likelihood of a catalog being selected in conflict scenarios") - fs.BoolVar(&i.Available, "available", true, "true means that the catalog should be active and serving data") + fs.BoolVar(&i.Available, "available", true, "determines whether a catalog should be active and serving data. default: true, meaning new catalogs serve their contents by default.") fs.IntVar(&i.PollIntervalMinutes, "source-poll-interval-minutes", 10, "catalog source polling interval [in minutes]") - fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels that will be added to the catalog") + fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new catalog") fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") + // sigs.k8s.io/controller-runtime/pkg/client supported dry-run values only. + fs.StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it if non-empty. One of: (All)") + fs.StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/extension_install.go b/internal/cmd/internal/olmv1/extension_install.go index 6bee6f0..f670f12 100644 --- a/internal/cmd/internal/olmv1/extension_install.go +++ b/internal/cmd/internal/olmv1/extension_install.go @@ -9,11 +9,21 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) +type extentionInstallOptions struct { + CatalogSelector string +} + func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionInstall(cfg) i.Logf = log.Printf + var extentionInstallOpts extentionInstallOptions + var err error cmd := &cobra.Command{ Use: "extension ", @@ -21,23 +31,69 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] - _, err := i.Run(cmd.Context()) + + if len(extentionInstallOpts.CatalogSelector) != 0 { + i.CatalogSelector, err = metav1.ParseToLabelSelector(extentionInstallOpts.CatalogSelector) + if err != nil { + log.Fatalf("unable to parse selector %s: %v", extentionInstallOpts.CatalogSelector, err) + } + } + switch i.UpgradeConstraintPolicy { + case "CatalogProvided", "SelfCertified", "": + default: + log.Fatalf("unrecognized Upgrade Constraint Policy %s, must be one of: (CatalogProvided|SelfCertified)", i.UpgradeConstraintPolicy) + } + switch i.CRDUpgradeSafetyEnforcement { + case "Strict", "None", "": + default: + log.Fatalf("unrecognized CRD Upgrade Safety Enforcement Policy %s, must be one of: (Strict|None)", i.CRDUpgradeSafetyEnforcement) + } + if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { + log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + } + extObj, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to install extension: %v", err) } log.Printf("extension %q created", i.ExtensionName) + + if err != nil { + log.Fatalf("failed to install extension %q: %v\n", i.ExtensionName, err) + } + if len(i.DryRun) == 0 { + log.Printf("extension %q created\n", i.ExtensionName) + return + } + if len(i.Output) == 0 { + log.Printf("extension %q created (dry run)\n", i.ExtensionName) + return + } + + extObj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + printFormattedExtensions(i.Output, *extObj) + }, } - bindOperatorInstallFlags(cmd.Flags(), i) + bindExtensionInstallFlags(cmd.Flags(), i, &extentionInstallOpts) return cmd } -func bindOperatorInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall) { - fs.StringVarP(&i.Namespace.Name, "namespace", "n", "", "namespace to install the operator in") - fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the operator to install") +func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall, o *extentionInstallOptions) { + fs.StringVarP(&i.Namespace.Name, "namespace", "n", "", "namespace to install the operator in") //infer? + fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the operator to install. Required.") fs.StringSliceVarP(&i.Channels, "channels", "c", []string{}, "channels which would be to used for getting updates e.g --channels \"stable,dev-preview,preview\"") fs.StringVarP(&i.Version, "version", "v", "", "version (or version range) from which to resolve bundles") fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation") fs.DurationVarP(&i.CleanupTimeout, "cleanup-timeout", "d", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") + fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new extension") + fs.StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") + fs.StringVar(&o.CatalogSelector, "catalog-selector", "", "Selector (label query) to filter catalogs to search for the package, "+ + "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ + "in (value3)). Matching objects must satisfy all of the specified label constraints.") + fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "CatalogProvided", "controls whether the upgrade path(s) defined in the catalog are enforced."+ + " One of CatalogProvided, SelfCertified), Default: CatalogProvided") + fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "Strict", "Output format for dry-run manifests. One of: (Strict, None), default: Strict") } diff --git a/internal/pkg/v1/action/catalog_create.go b/internal/pkg/v1/action/catalog_create.go index e8196a0..06d684a 100644 --- a/internal/pkg/v1/action/catalog_create.go +++ b/internal/pkg/v1/action/catalog_create.go @@ -9,6 +9,8 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" + + "sigs.k8s.io/controller-runtime/pkg/client" ) type CatalogCreate struct { @@ -22,6 +24,9 @@ type CatalogCreate struct { Available bool CleanupTimeout time.Duration + DryRun string + Output string + Logf func(string, ...interface{}) } @@ -32,10 +37,16 @@ func NewCatalogCreate(config *action.Configuration) *CatalogCreate { } } -func (i *CatalogCreate) Run(ctx context.Context) error { +func (i *CatalogCreate) Run(ctx context.Context) (*olmv1.ClusterCatalog, error) { catalog := i.buildCatalog() + if i.DryRun == DryRunAll { + if err := i.config.Client.Create(ctx, &catalog, client.DryRunAll); err != nil { + return nil, err + } + return &catalog, nil + } if err := i.config.Client.Create(ctx, &catalog); err != nil { - return err + return nil, err } var err error @@ -49,10 +60,10 @@ func (i *CatalogCreate) Run(ctx context.Context) error { if cleanupErr := deleteWithTimeout(i.config.Client, &catalog, i.CleanupTimeout); cleanupErr != nil { i.Logf("cleaning up failed catalog: %v", cleanupErr) } - return err + return nil, err } - return nil + return &catalog, nil } func (i *CatalogCreate) buildCatalog() olmv1.ClusterCatalog { diff --git a/internal/pkg/v1/action/catalog_create_test.go b/internal/pkg/v1/action/catalog_create_test.go index e872946..d812fb7 100644 --- a/internal/pkg/v1/action/catalog_create_test.go +++ b/internal/pkg/v1/action/catalog_create_test.go @@ -50,7 +50,7 @@ var _ = Describe("CatalogCreate", func() { creator.Priority = expectedCatalog.Spec.Priority creator.Labels = expectedCatalog.Labels creator.PollIntervalMinutes = *expectedCatalog.Spec.Source.Image.PollIntervalMinutes - err := creator.Run(context.TODO()) + _, err := creator.Run(context.TODO()) Expect(err).NotTo(BeNil()) Expect(err).To(MatchError(expectedErr)) @@ -65,7 +65,7 @@ var _ = Describe("CatalogCreate", func() { creator := internalaction.NewCatalogCreate(&action.Configuration{Client: testClient}) // fakeClient requires at least the catalogName to be set to run creator.CatalogName = expectedCatalog.Name - err := creator.Run(context.TODO()) + _, err := creator.Run(context.TODO()) Expect(err).NotTo(BeNil()) Expect(err).To(MatchError(expectedErr)) @@ -83,7 +83,7 @@ var _ = Describe("CatalogCreate", func() { creator := internalaction.NewCatalogCreate(&action.Configuration{Client: testClient}) // fakeClient requires at least the catalogName to be set to run creator.CatalogName = expectedCatalog.Name - err := creator.Run(context.TODO()) + _, err := creator.Run(context.TODO()) Expect(err).NotTo(BeNil()) Expect(err).To(MatchError(getErr)) diff --git a/internal/pkg/v1/action/extension_install.go b/internal/pkg/v1/action/extension_install.go index 0512679..4c57b45 100644 --- a/internal/pkg/v1/action/extension_install.go +++ b/internal/pkg/v1/action/extension_install.go @@ -11,7 +11,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" - ocv1 "github.com/operator-framework/operator-controller/api/v1" + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" ) @@ -26,6 +26,14 @@ type ExtensionInstall struct { ServiceAccount string CleanupTimeout time.Duration Logf func(string, ...interface{}) + + DryRun string + Output string + CatalogSelector *metav1.LabelSelector + UpgradeConstraintPolicy string + PreflightCRDUpgradeSafetyEnforcement string + CRDUpgradeSafetyEnforcement string + Labels map[string]string } type NamespaceConfig struct { Name string @@ -38,30 +46,40 @@ func NewExtensionInstall(cfg *action.Configuration) *ExtensionInstall { } } -func (i *ExtensionInstall) buildClusterExtension() ocv1.ClusterExtension { - extension := ocv1.ClusterExtension{ +func (i *ExtensionInstall) buildClusterExtension() olmv1.ClusterExtension { + extension := olmv1.ClusterExtension{ ObjectMeta: metav1.ObjectMeta{ - Name: i.ExtensionName, + Name: i.ExtensionName, + Labels: i.Labels, }, - Spec: ocv1.ClusterExtensionSpec{ - Source: ocv1.SourceConfig{ - SourceType: ocv1.SourceTypeCatalog, - Catalog: &ocv1.CatalogFilter{ + Spec: olmv1.ClusterExtensionSpec{ + Source: olmv1.SourceConfig{ + SourceType: olmv1.SourceTypeCatalog, + Catalog: &olmv1.CatalogFilter{ PackageName: i.PackageName, Version: i.Version, }, }, Namespace: i.Namespace.Name, - ServiceAccount: ocv1.ServiceAccountReference{ + ServiceAccount: olmv1.ServiceAccountReference{ Name: i.ServiceAccount, }, }, } + if i.CatalogSelector != nil { + extension.Spec.Source.Catalog.Selector = i.CatalogSelector + } + if len(i.UpgradeConstraintPolicy) > 0 { + extension.Spec.Source.Catalog.UpgradeConstraintPolicy = olmv1.UpgradeConstraintPolicy(i.UpgradeConstraintPolicy) + } + if len(i.CRDUpgradeSafetyEnforcement) > 0 { + extension.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(i.CRDUpgradeSafetyEnforcement) + } return extension } -func (i *ExtensionInstall) Run(ctx context.Context) (*ocv1.ClusterExtension, error) { +func (i *ExtensionInstall) Run(ctx context.Context) (*olmv1.ClusterExtension, error) { extension := i.buildClusterExtension() // Add Channels to extension @@ -69,8 +87,12 @@ func (i *ExtensionInstall) Run(ctx context.Context) (*ocv1.ClusterExtension, err extension.Spec.Source.Catalog.Channels = i.Channels } - // TODO: Add CatalogSelector to extension - + if i.DryRun == DryRunAll { + if err := i.config.Client.Create(ctx, &extension, client.DryRunAll); err != nil { + return nil, err + } + return &extension, nil + } // Create the extension if err := i.config.Client.Create(ctx, &extension); err != nil { return nil, err @@ -87,8 +109,8 @@ func (i *ExtensionInstall) Run(ctx context.Context) (*ocv1.ClusterExtension, err // waitForClusterExtensionInstalled waits for the ClusterExtension to be installed // and returns the ClusterExtension object -func (i *ExtensionInstall) waitForExtensionInstall(ctx context.Context) (*ocv1.ClusterExtension, error) { - clusterExtension := &ocv1.ClusterExtension{ +func (i *ExtensionInstall) waitForExtensionInstall(ctx context.Context) (*olmv1.ClusterExtension, error) { + clusterExtension := &olmv1.ClusterExtension{ ObjectMeta: metav1.ObjectMeta{ Name: i.ExtensionName, }, @@ -99,12 +121,12 @@ func (i *ExtensionInstall) waitForExtensionInstall(ctx context.Context) (*ocv1.C if err := i.config.Client.Get(conditionCtx, key, clusterExtension); err != nil { return false, err } - progressingCondition := meta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1.TypeProgressing) - if progressingCondition != nil && progressingCondition.Reason != ocv1.ReasonSucceeded { + progressingCondition := meta.FindStatusCondition(clusterExtension.Status.Conditions, olmv1.TypeProgressing) + if progressingCondition != nil && progressingCondition.Reason != olmv1.ReasonSucceeded { errMsg = progressingCondition.Message return false, nil } - if !meta.IsStatusConditionPresentAndEqual(clusterExtension.Status.Conditions, ocv1.TypeInstalled, metav1.ConditionTrue) { + if !meta.IsStatusConditionPresentAndEqual(clusterExtension.Status.Conditions, olmv1.TypeInstalled, metav1.ConditionTrue) { return false, nil } return true, nil @@ -118,7 +140,7 @@ func (i *ExtensionInstall) waitForExtensionInstall(ctx context.Context) (*ocv1.C } func (i *ExtensionInstall) cleanup(ctx context.Context) error { - clusterExtension := &ocv1.ClusterExtension{ + clusterExtension := &olmv1.ClusterExtension{ ObjectMeta: metav1.ObjectMeta{ Name: i.ExtensionName, }, diff --git a/internal/pkg/v1/action/helpers.go b/internal/pkg/v1/action/helpers.go index 3a76ab1..8063add 100644 --- a/internal/pkg/v1/action/helpers.go +++ b/internal/pkg/v1/action/helpers.go @@ -17,6 +17,7 @@ import ( ) const pollInterval = 250 * time.Millisecond +const DryRunAll = "All" func objectKeyForObject(obj client.Object) types.NamespacedName { return types.NamespacedName{ From 7b8547fd05a6547039d37adce974d8c8bf4ef98b Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Fri, 31 Oct 2025 10:02:22 -0400 Subject: [PATCH 05/11] reformat update commands Signed-off-by: Ankita Thomas --- internal/cmd/internal/olmv1/catalog_update.go | 37 +++++++++++++++++-- .../cmd/internal/olmv1/extension_update.go | 37 +++++++++++++++---- internal/pkg/v1/action/catalog_update.go | 11 ++++++ internal/pkg/v1/action/extension_update.go | 36 ++++++++++++++---- .../pkg/v1/action/extension_update_test.go | 14 +++---- 5 files changed, 110 insertions(+), 25 deletions(-) diff --git a/internal/cmd/internal/olmv1/catalog_update.go b/internal/cmd/internal/olmv1/catalog_update.go index 93b6534..b4ca641 100644 --- a/internal/cmd/internal/olmv1/catalog_update.go +++ b/internal/cmd/internal/olmv1/catalog_update.go @@ -6,6 +6,9 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewCatalogUpdateCmd allows updating a selected clustercatalog @@ -16,6 +19,7 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { var priority int32 var pollInterval int var labels map[string]string + var available string cmd := &cobra.Command{ Use: "catalog ", @@ -32,19 +36,46 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { if cmd.Flags().Changed("labels") { i.Labels = labels } - _, err := i.Run(cmd.Context()) + if len(available) > 0 { + switch available { + case "true": + i.AvailabilityMode = "Available" + case "false": + i.AvailabilityMode = "Unavailable" + default: + log.Fatalf("invalid value for `--available` %s; must be one of (true, false)\n", available) + } + } + if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { + log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + } + catalogObj, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to update catalog: %v", err) } - log.Printf("catalog %q updated", i.CatalogName) + + if len(i.DryRun) == 0 { + log.Printf("catalog %q updated\n", i.CatalogName) + return + } + if len(i.Output) == 0 { + log.Printf("catalog %q updated (dry run)\n", i.CatalogName) + return + } + + catalogObj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + printFormattedCatalogs(i.Output, *catalogObj) }, } cmd.Flags().Int32Var(&priority, "priority", 0, "priority determines the likelihood of a catalog being selected in conflict scenarios") + cmd.Flags().StringVar(&available, "available", "", "determines whether a catalog should be active and serving data. default: true, meaning new catalogs serve their contents by default.") cmd.Flags().IntVar(&pollInterval, "source-poll-interval-minutes", 5, "catalog source polling interval [in minutes]. Set to 0 or -1 to remove the polling interval.") cmd.Flags().StringToStringVar(&labels, "labels", map[string]string{}, "labels that will be added to the catalog") - cmd.Flags().StringVar(&i.AvailabilityMode, "availability-mode", "", "available means that the catalog should be active and serving data") cmd.Flags().StringVar(&i.ImageRef, "image", "", "Image reference for the catalog source. Leave unset to retain the current image.") cmd.Flags().BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead") + cmd.Flags().StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it if non-empty. One of: (All)") + cmd.Flags().StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") return cmd } diff --git a/internal/cmd/internal/olmv1/extension_update.go b/internal/cmd/internal/olmv1/extension_update.go index 9fe1f54..0025502 100644 --- a/internal/cmd/internal/olmv1/extension_update.go +++ b/internal/cmd/internal/olmv1/extension_update.go @@ -7,6 +7,9 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewExtensionUpdateCmd allows updating a selected operator @@ -15,16 +18,30 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { i.Logf = log.Printf cmd := &cobra.Command{ - Use: "extension ", + Use: "extension ", Short: "Update an extension", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - i.Package = args[0] - _, err := i.Run(cmd.Context()) + i.ExtensionName = args[0] + if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { + log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + } + extObj, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to update extension: %v", err) } - log.Printf("extension %q updated", i.Package) + if len(i.DryRun) == 0 { + log.Printf("extension %q updated\n", i.ExtensionName) + return + } + if len(i.Output) == 0 { + log.Printf("extension %q updated (dry run)\n", i.ExtensionName) + return + } + + extObj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + printFormattedExtensions(i.Output, *extObj) }, } bindExtensionUpdateFlags(cmd.Flags(), i) @@ -33,10 +50,16 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { } func bindExtensionUpdateFlags(fs *pflag.FlagSet, i *v1action.ExtensionUpdate) { - fs.StringVar(&i.Version, "version", "", "desired extension version (single or range) in semVer format. AND operation with channels") - fs.StringVar(&i.Selector, "selector", "", "filters the set of catalogs used in the bundle selection process. Empty means that all catalogs will be used in the bundle selection process") fs.StringArrayVar(&i.Channels, "channels", []string{}, "desired channels for extension versions. AND operation with version. Empty list means all available channels will be taken into consideration") - fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "", "controls whether the upgrade path(s) defined in the catalog are enforced. One of CatalogProvided|SelfCertified), Default: CatalogProvided") + fs.StringVar(&i.Version, "version", "", "desired extension version (single or range) in semVer format. AND operation with channels") + fs.StringVar(&i.Selector, "catalog-selector", "", "Selector (label query) to filter catalogs to search for the package, "+ + "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ + "in (value3)). Matching objects must satisfy all of the specified label constraints.") + fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "", "controls whether the upgrade path(s) defined in the catalog are enforced."+ + " One of CatalogProvided, SelfCertified), Default: CatalogProvided") fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels that will be set on the extension") fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead") + fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "", "Output format for dry-run manifests. One of: (Strict, None), default: Strict") + fs.StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/pkg/v1/action/catalog_update.go b/internal/pkg/v1/action/catalog_update.go index 7fa7c80..98d8609 100644 --- a/internal/pkg/v1/action/catalog_update.go +++ b/internal/pkg/v1/action/catalog_update.go @@ -10,6 +10,7 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" + "sigs.k8s.io/controller-runtime/pkg/client" ) type CatalogUpdate struct { @@ -24,6 +25,9 @@ type CatalogUpdate struct { IgnoreUnset bool Logf func(string, ...interface{}) + + DryRun string + Output string } func NewCatalogUpdate(config *action.Configuration) *CatalogUpdate { @@ -56,6 +60,13 @@ func (cu *CatalogUpdate) Run(ctx context.Context) (*olmv1.ClusterCatalog, error) cu.setDefaults(&catalog) cu.setUpdatedCatalog(&catalog) + if cu.DryRun == DryRunAll { + if err := cu.config.Client.Update(ctx, &catalog, client.DryRunAll); err != nil { + return nil, err + } + return &catalog, nil + } + if err := cu.config.Client.Update(ctx, &catalog); err != nil { return nil, err } diff --git a/internal/pkg/v1/action/extension_update.go b/internal/pkg/v1/action/extension_update.go index 4ef4032..3c6f0f0 100644 --- a/internal/pkg/v1/action/extension_update.go +++ b/internal/pkg/v1/action/extension_update.go @@ -10,6 +10,7 @@ import ( "github.com/blang/semver/v4" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" olmv1 "github.com/operator-framework/operator-controller/api/v1" @@ -17,9 +18,9 @@ import ( ) type ExtensionUpdate struct { - cfg *action.Configuration + config *action.Configuration - Package string + ExtensionName string Version string Channels []string @@ -34,12 +35,16 @@ type ExtensionUpdate struct { CleanupTimeout time.Duration Logf func(string, ...interface{}) + + CRDUpgradeSafetyEnforcement string + DryRun string + Output string } func NewExtensionUpdate(cfg *action.Configuration) *ExtensionUpdate { return &ExtensionUpdate{ - cfg: cfg, - Logf: func(string, ...interface{}) {}, + config: cfg, + Logf: func(string, ...interface{}) {}, } } @@ -47,8 +52,8 @@ func (ou *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, er var ext olmv1.ClusterExtension var err error - opKey := types.NamespacedName{Name: ou.Package} - if err = ou.cfg.Client.Get(ctx, opKey, &ext); err != nil { + opKey := types.NamespacedName{Name: ou.ExtensionName} + if err = ou.config.Client.Get(ctx, opKey, &ext); err != nil { return nil, err } @@ -76,11 +81,18 @@ func (ou *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, er } ou.prepareUpdatedExtension(&ext, constraintPolicy) - if err := ou.cfg.Client.Update(ctx, &ext); err != nil { + if ou.DryRun == DryRunAll { + if err := ou.config.Client.Update(ctx, &ext, client.DryRunAll); err != nil { + return nil, err + } + return &ext, nil + } + + if err := ou.config.Client.Update(ctx, &ext); err != nil { return nil, err } - if err := waitUntilExtensionStatusCondition(ctx, ou.cfg.Client, &ext, olmv1.TypeInstalled, metav1.ConditionTrue); err != nil { + if err := waitUntilExtensionStatusCondition(ctx, ou.config.Client, &ext, olmv1.TypeInstalled, metav1.ConditionTrue); err != nil { return nil, fmt.Errorf("timed out waiting for extension: %w", err) } @@ -92,6 +104,9 @@ func (ou *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { if ou.UpgradeConstraintPolicy == "" { ou.UpgradeConstraintPolicy = string(olmv1.UpgradeConstraintPolicyCatalogProvided) } + if ou.CRDUpgradeSafetyEnforcement == "" { + ou.CRDUpgradeSafetyEnforcement = string(olmv1.CRDUpgradeSafetyEnforcementStrict) + } return } @@ -108,6 +123,9 @@ func (ou *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { if ou.UpgradeConstraintPolicy == "" { ou.UpgradeConstraintPolicy = string(catalogSrc.UpgradeConstraintPolicy) } + if ou.CRDUpgradeSafetyEnforcement == "" { + ou.CRDUpgradeSafetyEnforcement = string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) + } if len(ou.Labels) == 0 { ou.Labels = ext.Labels } @@ -130,6 +148,7 @@ func (ou *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPol slices.Equal(catalogSrc.Channels, ou.Channels) && catalogSrc.UpgradeConstraintPolicy == constraintPolicy && maps.Equal(ext.Labels, ou.Labels) && + string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) == ou.CRDUpgradeSafetyEnforcement && sameSelectors { return false } @@ -143,4 +162,5 @@ func (ou *ExtensionUpdate) prepareUpdatedExtension(ext *olmv1.ClusterExtension, ext.Spec.Source.Catalog.Selector = ou.parsedSelector ext.Spec.Source.Catalog.Channels = ou.Channels ext.Spec.Source.Catalog.UpgradeConstraintPolicy = constraintPolicy + ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(ou.CRDUpgradeSafetyEnforcement) } diff --git a/internal/pkg/v1/action/extension_update_test.go b/internal/pkg/v1/action/extension_update_test.go index 4e33de5..81d1a75 100644 --- a/internal/pkg/v1/action/extension_update_test.go +++ b/internal/pkg/v1/action/extension_update_test.go @@ -39,7 +39,7 @@ var _ = Describe("ExtensionUpdate", func() { cfg := setupEnv() updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "does-not-exist" + updater.ExtensionName = "does-not-exist" ext, err := updater.Run(context.TODO()) Expect(err).NotTo(BeNil()) @@ -51,7 +51,7 @@ var _ = Describe("ExtensionUpdate", func() { cfg := setupEnv(buildExtension("test", withSourceType("unknown"))) updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "test" + updater.ExtensionName = "test" ext, err := updater.Run(context.TODO()) Expect(err).NotTo(BeNil()) @@ -67,7 +67,7 @@ var _ = Describe("ExtensionUpdate", func() { ) updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "test" + updater.ExtensionName = "test" ext, err := updater.Run(context.TODO()) Expect(err).NotTo(BeNil()) @@ -86,7 +86,7 @@ var _ = Describe("ExtensionUpdate", func() { )) updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "test" + updater.ExtensionName = "test" updater.IgnoreUnset = true ext, err := updater.Run(context.TODO()) @@ -103,7 +103,7 @@ var _ = Describe("ExtensionUpdate", func() { ) updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "test" + updater.ExtensionName = "test" updater.Version = "10-4" ext, err := updater.Run(context.TODO()) @@ -124,7 +124,7 @@ var _ = Describe("ExtensionUpdate", func() { cancel() updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "test" + updater.ExtensionName = "test" updater.Version = "10.0.4" updater.Channels = []string{"a", "b"} updater.Labels = map[string]string{"c": "d"} @@ -152,7 +152,7 @@ var _ = Describe("ExtensionUpdate", func() { }() updater := internalaction.NewExtensionUpdate(&cfg) - updater.Package = "test" + updater.ExtensionName = "test" updater.Version = "10.0.4" updater.Channels = []string{"a", "b"} updater.Labels = map[string]string{"c": "d"} From 4a27912724b2a863870eec76b535bb66ea7ad88a Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Fri, 31 Oct 2025 10:44:49 -0400 Subject: [PATCH 06/11] refactor delete commands Signed-off-by: Ankita Thomas --- internal/cmd/internal/olmv1/catalog_delete.go | 2 + .../cmd/internal/olmv1/extension_delete.go | 38 ++++++++++++------ internal/pkg/v1/action/catalog_delete.go | 28 ++++++++----- internal/pkg/v1/action/extension_delete.go | 39 +++++++++++-------- 4 files changed, 70 insertions(+), 37 deletions(-) diff --git a/internal/cmd/internal/olmv1/catalog_delete.go b/internal/cmd/internal/olmv1/catalog_delete.go index c720622..752004d 100644 --- a/internal/cmd/internal/olmv1/catalog_delete.go +++ b/internal/cmd/internal/olmv1/catalog_delete.go @@ -47,4 +47,6 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { func bindCatalogDeleteFlags(fs *pflag.FlagSet, d *v1action.CatalogDelete) { fs.BoolVar(&d.DeleteAll, "all", false, "delete all catalogs") + fs.StringVar(&d.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&d.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/extension_delete.go b/internal/cmd/internal/olmv1/extension_delete.go index bc1ff94..5b58db1 100644 --- a/internal/cmd/internal/olmv1/extension_delete.go +++ b/internal/cmd/internal/olmv1/extension_delete.go @@ -7,6 +7,9 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { @@ -22,23 +25,34 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { cascades to the deletion of all operands.`, Args: cobra.RangeArgs(0, 1), Run: func(cmd *cobra.Command, args []string) { - if len(args) == 0 { - extensions, err := e.Run(cmd.Context()) - if err != nil { - log.Fatalf("failed deleting extension: %v", err) + if len(e.DryRun) > 0 && e.DryRun != v1action.DryRunAll { + log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", e.DryRun, v1action.DryRunAll) + } + if len(args) != 0 { + e.ExtensionName = args[0] + } + extensions, err := e.Run(cmd.Context()) + if err != nil { + log.Fatalf("failed to delete extension: %v", err) + } + if len(e.DryRun) == 0 { + for _, extn := range extensions { + log.Printf("extension %s deleted", extn.Name) } + return + } + if len(e.Output) == 0 { for _, extn := range extensions { - log.Printf("extension %q deleted", extn) + log.Printf("extension %s deleted(dry run)\n", extn.Name) } - return } - e.ExtensionName = args[0] - _, errs := e.Run(cmd.Context()) - if errs != nil { - log.Fatalf("delete extension: %v", errs) + + for _, i := range extensions { + i.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) } - log.Printf("deleted extension %q", e.ExtensionName) + printFormattedExtensions(e.Output, extensions...) }, } bindExtensionDeleteFlags(cmd.Flags(), e) @@ -47,4 +61,6 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { func bindExtensionDeleteFlags(fs *pflag.FlagSet, e *v1action.ExtensionDeletion) { fs.BoolVarP(&e.DeleteAll, "all", "a", false, "delete all extensions") + fs.StringVar(&e.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&e.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/pkg/v1/action/catalog_delete.go b/internal/pkg/v1/action/catalog_delete.go index d388827..66b0081 100644 --- a/internal/pkg/v1/action/catalog_delete.go +++ b/internal/pkg/v1/action/catalog_delete.go @@ -8,6 +8,7 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" + "sigs.k8s.io/controller-runtime/pkg/client" ) type CatalogDelete struct { @@ -16,6 +17,9 @@ type CatalogDelete struct { DeleteAll bool Logf func(string, ...interface{}) + + DryRun string + Output string } func NewCatalogDelete(cfg *action.Configuration) *CatalogDelete { @@ -25,7 +29,7 @@ func NewCatalogDelete(cfg *action.Configuration) *CatalogDelete { } } -func (cd *CatalogDelete) Run(ctx context.Context) ([]string, error) { +func (cd *CatalogDelete) Run(ctx context.Context) ([]olmv1.ClusterCatalog, error) { // validate if cd.DeleteAll && cd.CatalogName != "" { return nil, ErrNameAndSelector @@ -33,7 +37,8 @@ func (cd *CatalogDelete) Run(ctx context.Context) ([]string, error) { // delete single, specified catalog if !cd.DeleteAll { - return nil, cd.deleteCatalog(ctx, cd.CatalogName) + obj, err := cd.deleteCatalog(ctx, cd.CatalogName) + return []olmv1.ClusterCatalog{obj}, err } // delete all existing catalogs @@ -46,24 +51,29 @@ func (cd *CatalogDelete) Run(ctx context.Context) ([]string, error) { } errs := make([]error, 0, len(catatalogList.Items)) - names := make([]string, 0, len(catatalogList.Items)) + result := []olmv1.ClusterCatalog{} for _, catalog := range catatalogList.Items { - names = append(names, catalog.Name) - if err := cd.deleteCatalog(ctx, catalog.Name); err != nil { + if obj, err := cd.deleteCatalog(ctx, catalog.Name); err != nil { errs = append(errs, fmt.Errorf("failed deleting catalog %q: %w", catalog.Name, err)) + } else { + result = append(result, obj) } } - return names, errors.Join(errs...) + return result, errors.Join(errs...) } -func (cd *CatalogDelete) deleteCatalog(ctx context.Context, name string) error { +func (cd *CatalogDelete) deleteCatalog(ctx context.Context, name string) (olmv1.ClusterCatalog, error) { op := &olmv1.ClusterCatalog{} op.SetName(name) + if cd.DryRun == DryRunAll { + err := cd.config.Client.Delete(ctx, op, client.DryRunAll) + return *op, err + } if err := cd.config.Client.Delete(ctx, op); err != nil { - return err + return *op, err } - return waitForDeletion(ctx, cd.config.Client, op) + return *op, waitForDeletion(ctx, cd.config.Client, op) } diff --git a/internal/pkg/v1/action/extension_delete.go b/internal/pkg/v1/action/extension_delete.go index 488fce4..40a4118 100644 --- a/internal/pkg/v1/action/extension_delete.go +++ b/internal/pkg/v1/action/extension_delete.go @@ -4,13 +4,11 @@ import ( "context" "errors" "fmt" - "strings" - - apierrors "k8s.io/apimachinery/pkg/api/errors" olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" + "sigs.k8s.io/controller-runtime/pkg/client" ) // ExtensionDeletion deletes an extension or all extensions in the cluster @@ -19,6 +17,9 @@ type ExtensionDeletion struct { ExtensionName string DeleteAll bool Logf func(string, ...interface{}) + + DryRun string + Output string } // NewExtensionDelete creates a new ExtensionDeletion action @@ -31,12 +32,13 @@ func NewExtensionDelete(cfg *action.Configuration) *ExtensionDeletion { } } -func (u *ExtensionDeletion) Run(ctx context.Context) ([]string, error) { +func (u *ExtensionDeletion) Run(ctx context.Context) ([]olmv1.ClusterExtension, error) { if u.DeleteAll && u.ExtensionName != "" { return nil, fmt.Errorf("cannot specify both --all and an extension name") } if !u.DeleteAll { - return u.deleteExtension(ctx, u.ExtensionName) + ext, err := u.deleteExtension(ctx, u.ExtensionName) + return []olmv1.ClusterExtension{ext}, err } // delete all existing extensions @@ -44,24 +46,26 @@ func (u *ExtensionDeletion) Run(ctx context.Context) ([]string, error) { } // deleteExtension deletes a single extension in the cluster -func (u *ExtensionDeletion) deleteExtension(ctx context.Context, extName string) ([]string, error) { +func (u *ExtensionDeletion) deleteExtension(ctx context.Context, extName string) (olmv1.ClusterExtension, error) { op := &olmv1.ClusterExtension{} op.SetName(extName) op.SetGroupVersionKind(olmv1.GroupVersion.WithKind("ClusterExtension")) - lowerKind := strings.ToLower(op.GetObjectKind().GroupVersionKind().Kind) + + if u.DryRun == DryRunAll { + err := u.config.Client.Delete(ctx, op, client.DryRunAll) + return *op, err + } + err := u.config.Client.Delete(ctx, op) if err != nil { - if !apierrors.IsNotFound(err) { - return []string{u.ExtensionName}, fmt.Errorf("delete %s %q: %v", lowerKind, op.GetName(), err) - } - return nil, err + return *op, err } // wait for deletion - return []string{u.ExtensionName}, waitForDeletion(ctx, u.config.Client, op) + return *op, waitForDeletion(ctx, u.config.Client, op) } // deleteAllExtensions deletes all extensions in the cluster -func (u *ExtensionDeletion) deleteAllExtensions(ctx context.Context) ([]string, error) { +func (u *ExtensionDeletion) deleteAllExtensions(ctx context.Context) ([]olmv1.ClusterExtension, error) { var extensionList olmv1.ClusterExtensionList if err := u.config.Client.List(ctx, &extensionList); err != nil { return nil, err @@ -70,12 +74,13 @@ func (u *ExtensionDeletion) deleteAllExtensions(ctx context.Context) ([]string, return nil, ErrNoResourcesFound } errs := make([]error, 0, len(extensionList.Items)) - names := make([]string, 0, len(extensionList.Items)) + result := []olmv1.ClusterExtension{} for _, extension := range extensionList.Items { - names = append(names, extension.Name) - if _, err := u.deleteExtension(ctx, extension.Name); err != nil { + if op, err := u.deleteExtension(ctx, extension.Name); err != nil { errs = append(errs, fmt.Errorf("failed deleting extension %q: %w", extension.Name, err)) + } else { + result = append(result, op) } } - return names, errors.Join(errs...) + return result, errors.Join(errs...) } From a6c02a8297256e07fc41c7b7590cc3867443c236 Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Fri, 31 Oct 2025 11:21:28 -0400 Subject: [PATCH 07/11] spinner Signed-off-by: Ankita Thomas --- go.mod | 4 ++ go.sum | 11 +++++ internal/cmd/internal/olmv1/catalog_create.go | 4 +- internal/cmd/internal/olmv1/catalog_delete.go | 41 +++++++++++++------ internal/cmd/internal/olmv1/catalog_update.go | 4 +- .../cmd/internal/olmv1/extension_delete.go | 6 +-- .../cmd/internal/olmv1/extension_install.go | 8 ++-- .../cmd/internal/olmv1/extension_update.go | 8 ++-- internal/cmd/internal/olmv1/flags.go | 4 +- internal/cmd/internal/olmv1/printing.go | 22 ++++++++-- internal/pkg/v1/action/helpers.go | 13 ++++++ 11 files changed, 91 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 23acf44..1cf127d 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.24.4 require ( github.com/blang/semver/v4 v4.0.0 + github.com/briandowns/spinner v1.23.2 github.com/containerd/containerd v1.7.28 github.com/containerd/platforms v0.2.1 github.com/onsi/ginkgo v1.16.5 @@ -56,6 +57,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.8.0 // indirect @@ -85,6 +87,8 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/moby/sys/capability v0.4.0 // indirect diff --git a/go.sum b/go.sum index 2341021..8691120 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w= +github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM= github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -103,6 +105,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -224,6 +228,11 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= @@ -472,6 +481,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= diff --git a/internal/cmd/internal/olmv1/catalog_create.go b/internal/cmd/internal/olmv1/catalog_create.go index 294916e..6bf8523 100644 --- a/internal/cmd/internal/olmv1/catalog_create.go +++ b/internal/cmd/internal/olmv1/catalog_create.go @@ -61,6 +61,6 @@ func bindCatalogCreateFlags(fs *pflag.FlagSet, i *v1action.CatalogCreate) { fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new catalog") fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") // sigs.k8s.io/controller-runtime/pkg/client supported dry-run values only. - fs.StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it if non-empty. One of: (All)") - fs.StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") + fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it if non-empty. One of: (All)") + fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/catalog_delete.go b/internal/cmd/internal/olmv1/catalog_delete.go index 752004d..578dfa0 100644 --- a/internal/cmd/internal/olmv1/catalog_delete.go +++ b/internal/cmd/internal/olmv1/catalog_delete.go @@ -7,6 +7,9 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewCatalogDeleteCmd allows deleting either a single or all @@ -21,23 +24,35 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { Args: cobra.RangeArgs(0, 1), Short: "Delete either a single or all of the existing catalogs", Run: func(cmd *cobra.Command, args []string) { - if len(args) == 0 { - catalogs, err := d.Run(cmd.Context()) - if err != nil { - log.Fatalf("failed deleting catalogs: %v", err) + if len(args) > 0 { + d.CatalogName = args[0] + } + catalogs, err := d.Run(cmd.Context()) + if err != nil { + log.Fatalf("failed to delete catalog(s): %v", err) + } + + if len(d.DryRun) == 0 { + for _, extn := range catalogs { + log.Printf("extension %s deleted", extn.Name) } - for _, catalog := range catalogs { - log.Printf("catalog %q deleted", catalog) + return + } + if len(d.Output) == 0 { + for _, extn := range catalogs { + log.Printf("extension %s deleted (dry run)\n", extn.Name) } - return } - d.CatalogName = args[0] - if _, err := d.Run(cmd.Context()); err != nil { - log.Fatalf("failed to delete catalog %q: %v", d.CatalogName, err) + for _, i := range catalogs { + i.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + } + printFormattedCatalogs(d.Output, catalogs...) + for _, catalog := range catalogs { + log.Printf("catalog %q deleted", catalog) } - log.Printf("catalog %q deleted", d.CatalogName) }, } bindCatalogDeleteFlags(cmd.Flags(), d) @@ -47,6 +62,6 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { func bindCatalogDeleteFlags(fs *pflag.FlagSet, d *v1action.CatalogDelete) { fs.BoolVar(&d.DeleteAll, "all", false, "delete all catalogs") - fs.StringVar(&d.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&d.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") + fs.StringVar(&d.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&d.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/catalog_update.go b/internal/cmd/internal/olmv1/catalog_update.go index b4ca641..37ba26b 100644 --- a/internal/cmd/internal/olmv1/catalog_update.go +++ b/internal/cmd/internal/olmv1/catalog_update.go @@ -74,8 +74,8 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { cmd.Flags().StringToStringVar(&labels, "labels", map[string]string{}, "labels that will be added to the catalog") cmd.Flags().StringVar(&i.ImageRef, "image", "", "Image reference for the catalog source. Leave unset to retain the current image.") cmd.Flags().BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead") - cmd.Flags().StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it if non-empty. One of: (All)") - cmd.Flags().StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") + cmd.Flags().StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it if non-empty. One of: (All)") + cmd.Flags().StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") return cmd } diff --git a/internal/cmd/internal/olmv1/extension_delete.go b/internal/cmd/internal/olmv1/extension_delete.go index 5b58db1..838a400 100644 --- a/internal/cmd/internal/olmv1/extension_delete.go +++ b/internal/cmd/internal/olmv1/extension_delete.go @@ -43,7 +43,7 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { } if len(e.Output) == 0 { for _, extn := range extensions { - log.Printf("extension %s deleted(dry run)\n", extn.Name) + log.Printf("extension %s deleted (dry run)\n", extn.Name) } return } @@ -61,6 +61,6 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { func bindExtensionDeleteFlags(fs *pflag.FlagSet, e *v1action.ExtensionDeletion) { fs.BoolVarP(&e.DeleteAll, "all", "a", false, "delete all extensions") - fs.StringVar(&e.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&e.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") + fs.StringVar(&e.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&e.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/extension_install.go b/internal/cmd/internal/olmv1/extension_install.go index f670f12..e5c433c 100644 --- a/internal/cmd/internal/olmv1/extension_install.go +++ b/internal/cmd/internal/olmv1/extension_install.go @@ -88,12 +88,12 @@ func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall, fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation") fs.DurationVarP(&i.CleanupTimeout, "cleanup-timeout", "d", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new extension") - fs.StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") - fs.StringVar(&o.CatalogSelector, "catalog-selector", "", "Selector (label query) to filter catalogs to search for the package, "+ + fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") + fs.StringVar(&o.CatalogSelector, "catalog-selector", "", "selector (label query) to filter catalogs to search for the package, "+ "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ "in (value3)). Matching objects must satisfy all of the specified label constraints.") fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "CatalogProvided", "controls whether the upgrade path(s) defined in the catalog are enforced."+ " One of CatalogProvided, SelfCertified), Default: CatalogProvided") - fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "Strict", "Output format for dry-run manifests. One of: (Strict, None), default: Strict") + fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "Strict", "policy for preflight CRD Upgrade safety checks. One of: (Strict, None), default: Strict") } diff --git a/internal/cmd/internal/olmv1/extension_update.go b/internal/cmd/internal/olmv1/extension_update.go index 0025502..1a4f65b 100644 --- a/internal/cmd/internal/olmv1/extension_update.go +++ b/internal/cmd/internal/olmv1/extension_update.go @@ -52,14 +52,14 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { func bindExtensionUpdateFlags(fs *pflag.FlagSet, i *v1action.ExtensionUpdate) { fs.StringArrayVar(&i.Channels, "channels", []string{}, "desired channels for extension versions. AND operation with version. Empty list means all available channels will be taken into consideration") fs.StringVar(&i.Version, "version", "", "desired extension version (single or range) in semVer format. AND operation with channels") - fs.StringVar(&i.Selector, "catalog-selector", "", "Selector (label query) to filter catalogs to search for the package, "+ + fs.StringVar(&i.Selector, "catalog-selector", "", "selector (label query) to filter catalogs to search for the package, "+ "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ "in (value3)). Matching objects must satisfy all of the specified label constraints.") fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "", "controls whether the upgrade path(s) defined in the catalog are enforced."+ " One of CatalogProvided, SelfCertified), Default: CatalogProvided") fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels that will be set on the extension") fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead") - fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "", "Output format for dry-run manifests. One of: (Strict, None), default: Strict") - fs.StringVar(&i.DryRun, "dry-run", "", "Display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&i.Output, "output", "o", "", "Output format for dry-run manifests. One of: (json, yaml)") + fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "", "policy for preflight CRD Upgrade safety checks. One of: (Strict, None), default: Strict") + fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/flags.go b/internal/cmd/internal/olmv1/flags.go index c9ff4e1..f6890a8 100644 --- a/internal/cmd/internal/olmv1/flags.go +++ b/internal/cmd/internal/olmv1/flags.go @@ -8,8 +8,8 @@ type getOptions struct { } func bindGetFlags(fs *pflag.FlagSet, o *getOptions) { - fs.StringVarP(&o.Output, "output", "o", "", "Output format. One of: (json, yaml)") - fs.StringVarP(&o.Selector, "selector", "l", "", "Selector (label query) to filter on, "+ + fs.StringVarP(&o.Output, "output", "o", "", "output format. One of: (json, yaml)") + fs.StringVarP(&o.Selector, "selector", "l", "", "selector (label query) to filter on, "+ "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ "in (value3)). Matching objects must satisfy all of the specified label constraints.") diff --git a/internal/cmd/internal/olmv1/printing.go b/internal/cmd/internal/olmv1/printing.go index 58b9005..8608747 100644 --- a/internal/cmd/internal/olmv1/printing.go +++ b/internal/cmd/internal/olmv1/printing.go @@ -13,6 +13,7 @@ import ( "github.com/blang/semver/v4" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/util/json" "k8s.io/cli-runtime/pkg/printers" @@ -31,7 +32,10 @@ func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterEx case "yaml": printer := printers.YAMLPrinter{} if len(extensions) > 1 { - if err := printer.PrintObj(&olmv1.ClusterExtensionList{Items: extensions}, os.Stdout); err != nil { + obj := &olmv1.ClusterExtensionList{Items: extensions} + obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to YAML: %v\n", err) } return @@ -43,7 +47,11 @@ func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterEx case "json": printer := printers.JSONPrinter{} if len(extensions) > 1 { - if err := printer.PrintObj(&olmv1.ClusterExtensionList{Items: extensions}, os.Stdout); err != nil { + obj := &olmv1.ClusterExtensionList{Items: extensions} + obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + + if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to JSON: %v\n", err) } return @@ -87,7 +95,10 @@ func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalo case "yaml": printer := printers.YAMLPrinter{} if len(catalogs) > 1 { - if err := printer.PrintObj(&olmv1.ClusterCatalogList{Items: catalogs}, os.Stdout); err != nil { + obj := &olmv1.ClusterCatalogList{Items: catalogs} + obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to YAML: %v\n", err) } return @@ -99,7 +110,10 @@ func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalo case "json": printer := printers.JSONPrinter{} if len(catalogs) > 1 { - if err := printer.PrintObj(&olmv1.ClusterCatalogList{Items: catalogs}, os.Stdout); err != nil { + obj := &olmv1.ClusterCatalogList{Items: catalogs} + obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to JSON: %v\n", err) } return diff --git a/internal/pkg/v1/action/helpers.go b/internal/pkg/v1/action/helpers.go index 8063add..85e32d0 100644 --- a/internal/pkg/v1/action/helpers.go +++ b/internal/pkg/v1/action/helpers.go @@ -13,6 +13,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/briandowns/spinner" olmv1 "github.com/operator-framework/operator-controller/api/v1" ) @@ -33,6 +34,9 @@ func waitUntilCatalogStatusCondition( conditionType string, conditionStatus metav1.ConditionStatus, ) error { + s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Start() + defer s.Stop() opKey := objectKeyForObject(catalog) return wait.PollUntilContextCancel(ctx, pollInterval, true, func(conditionCtx context.Context) (bool, error) { if err := cl.Get(conditionCtx, opKey, catalog); err != nil { @@ -55,6 +59,9 @@ func waitUntilExtensionStatusCondition( conditionType string, conditionStatus metav1.ConditionStatus, ) error { + s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Start() + defer s.Stop() opKey := objectKeyForObject(extension) return wait.PollUntilContextCancel(ctx, pollInterval, true, func(conditionCtx context.Context) (bool, error) { if err := cl.Get(conditionCtx, opKey, extension); err != nil { @@ -71,6 +78,9 @@ func waitUntilExtensionStatusCondition( } func deleteWithTimeout(cl deleter, obj client.Object, timeout time.Duration) error { + s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Start() + defer s.Stop() ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -82,6 +92,9 @@ func deleteWithTimeout(cl deleter, obj client.Object, timeout time.Duration) err } func waitForDeletion(ctx context.Context, cl getter, objs ...client.Object) error { + s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Start() + defer s.Stop() for _, obj := range objs { lowerKind := strings.ToLower(obj.GetObjectKind().GroupVersionKind().Kind) key := objectKeyForObject(obj) From dbbf5fc87fe5d116174bc89add578985e053279f Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Fri, 14 Nov 2025 10:54:23 -0500 Subject: [PATCH 08/11] fix formatting and type conversion Signed-off-by: Ankita Thomas --- internal/cmd/catalog_remove.go | 2 +- internal/cmd/internal/olmv1/catalog_delete.go | 15 ++- internal/cmd/internal/olmv1/catalog_get.go | 16 +-- internal/cmd/internal/olmv1/extension_get.go | 7 ++ .../cmd/internal/olmv1/extension_install.go | 17 +-- internal/cmd/olmv1.go | 4 +- internal/pkg/v1/action/catalog_create.go | 9 +- internal/pkg/v1/action/catalog_delete.go | 26 ++--- internal/pkg/v1/action/catalog_get.go | 10 +- internal/pkg/v1/action/catalog_search.go | 7 +- internal/pkg/v1/action/catalog_search_test.go | 109 ++++++++++++++++++ internal/pkg/v1/action/catalog_update.go | 75 ++++++------ internal/pkg/v1/action/extension_delete.go | 31 ++--- internal/pkg/v1/action/extension_get.go | 3 +- internal/pkg/v1/action/extension_install.go | 32 +++-- internal/pkg/v1/action/extension_update.go | 108 +++++++++-------- internal/pkg/v1/action/helpers.go | 4 + 17 files changed, 302 insertions(+), 173 deletions(-) create mode 100644 internal/pkg/v1/action/catalog_search_test.go diff --git a/internal/cmd/catalog_remove.go b/internal/cmd/catalog_remove.go index fa03131..ae1931e 100644 --- a/internal/cmd/catalog_remove.go +++ b/internal/cmd/catalog_remove.go @@ -12,7 +12,7 @@ func newCatalogRemoveCmd(cfg *action.Configuration) *cobra.Command { u := internalaction.NewCatalogRemove(cfg) cmd := &cobra.Command{ Use: "remove ", - Short: "Remove a operator catalog", + Short: "Remove an operator catalog", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { u.CatalogName = args[0] diff --git a/internal/cmd/internal/olmv1/catalog_delete.go b/internal/cmd/internal/olmv1/catalog_delete.go index 578dfa0..6b8f24d 100644 --- a/internal/cmd/internal/olmv1/catalog_delete.go +++ b/internal/cmd/internal/olmv1/catalog_delete.go @@ -25,6 +25,9 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { Short: "Delete either a single or all of the existing catalogs", Run: func(cmd *cobra.Command, args []string) { if len(args) > 0 { + if d.DeleteAll { + log.Fatalf("failed to delete catalog: cannot specify both --all and a catalog name") + } d.CatalogName = args[0] } catalogs, err := d.Run(cmd.Context()) @@ -33,14 +36,14 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { } if len(d.DryRun) == 0 { - for _, extn := range catalogs { - log.Printf("extension %s deleted", extn.Name) + for _, catn := range catalogs { + log.Printf("catalog %s deleted", catn.Name) } return } if len(d.Output) == 0 { - for _, extn := range catalogs { - log.Printf("extension %s deleted (dry run)\n", extn.Name) + for _, catn := range catalogs { + log.Printf("catalog %s deleted (dry run)\n", catn.Name) } return } @@ -51,7 +54,7 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { } printFormattedCatalogs(d.Output, catalogs...) for _, catalog := range catalogs { - log.Printf("catalog %q deleted", catalog) + log.Printf("catalog %q deleted", catalog.Name) } }, } @@ -61,7 +64,7 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { } func bindCatalogDeleteFlags(fs *pflag.FlagSet, d *v1action.CatalogDelete) { - fs.BoolVar(&d.DeleteAll, "all", false, "delete all catalogs") + fs.BoolVarP(&d.DeleteAll, "all", "a", false, "delete all catalogs") fs.StringVar(&d.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") fs.StringVarP(&d.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/catalog_get.go b/internal/cmd/internal/olmv1/catalog_get.go index eb585ca..9a2ef6f 100644 --- a/internal/cmd/internal/olmv1/catalog_get.go +++ b/internal/cmd/internal/olmv1/catalog_get.go @@ -6,7 +6,9 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - "k8s.io/apimachinery/pkg/labels" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewCatalogInstalledGetCmd handles get commands in the form of: @@ -33,16 +35,16 @@ func NewCatalogInstalledGetCmd(cfg *action.Configuration) *cobra.Command { default: log.Fatalf("unrecognized output format %s", catalogGetOptions.Output) } - if len(catalogGetOptions.Selector) > 0 { - i.Selector, err = labels.Parse(catalogGetOptions.Selector) - if err != nil { - log.Fatalf("unable to parse selector %s: %v", catalogGetOptions.Selector, err) - } - } + i.Selector = catalogGetOptions.Selector installedCatalogs, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed getting installed catalog(s): %v", err) } + + for i := range installedCatalogs { + installedCatalogs[i].GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + } printFormattedCatalogs(catalogGetOptions.Output, installedCatalogs...) }, } diff --git a/internal/cmd/internal/olmv1/extension_get.go b/internal/cmd/internal/olmv1/extension_get.go index 2efdbf1..a4cf60c 100644 --- a/internal/cmd/internal/olmv1/extension_get.go +++ b/internal/cmd/internal/olmv1/extension_get.go @@ -7,6 +7,9 @@ import ( v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" "k8s.io/apimachinery/pkg/labels" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewExtensionInstalledGetCmd handles get commands in the form of: @@ -39,6 +42,10 @@ func NewExtensionInstalledGetCmd(cfg *action.Configuration) *cobra.Command { log.Fatalf("failed getting installed extension(s): %v", err) } + for i := range installedExtensions { + installedExtensions[i].GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + } printFormattedExtensions(extensionGetOptions.Output, installedExtensions...) }, } diff --git a/internal/cmd/internal/olmv1/extension_install.go b/internal/cmd/internal/olmv1/extension_install.go index e5c433c..68918df 100644 --- a/internal/cmd/internal/olmv1/extension_install.go +++ b/internal/cmd/internal/olmv1/extension_install.go @@ -15,14 +15,14 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -type extentionInstallOptions struct { +type extensionInstallOptions struct { CatalogSelector string } func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionInstall(cfg) i.Logf = log.Printf - var extentionInstallOpts extentionInstallOptions + var extentionInstallOpts extensionInstallOptions var err error cmd := &cobra.Command{ @@ -53,12 +53,7 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { } extObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to install extension: %v", err) - } - log.Printf("extension %q created", i.ExtensionName) - - if err != nil { - log.Fatalf("failed to install extension %q: %v\n", i.ExtensionName, err) + log.Fatalf("failed to install extension %q: %w\n", i.ExtensionName, err) } if len(i.DryRun) == 0 { log.Printf("extension %q created\n", i.ExtensionName) @@ -80,10 +75,10 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { return cmd } -func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall, o *extentionInstallOptions) { - fs.StringVarP(&i.Namespace.Name, "namespace", "n", "", "namespace to install the operator in") //infer? +func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall, o *extensionInstallOptions) { + fs.StringVarP(&i.Namespace.Name, "namespace", "n", "olmv1-system", "namespace to install the operator in") //infer? fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the operator to install. Required.") - fs.StringSliceVarP(&i.Channels, "channels", "c", []string{}, "channels which would be to used for getting updates e.g --channels \"stable,dev-preview,preview\"") + fs.StringSliceVarP(&i.Channels, "channels", "c", []string{}, "channels to be used for getting updates e.g --channels \"stable,dev-preview,preview\"") fs.StringVarP(&i.Version, "version", "v", "", "version (or version range) from which to resolve bundles") fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation") fs.DurationVarP(&i.CleanupTimeout, "cleanup-timeout", "d", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") diff --git a/internal/cmd/olmv1.go b/internal/cmd/olmv1.go index a4ce21d..8659722 100644 --- a/internal/cmd/olmv1.go +++ b/internal/cmd/olmv1.go @@ -10,8 +10,8 @@ import ( func newOlmV1Cmd(cfg *action.Configuration) *cobra.Command { cmd := &cobra.Command{ Use: "olmv1", - Short: "Manage extensions via OLMv1 in a cluster from the command line", - Long: "Manage extensions via OLMv1 in a cluster from the command line.", + Short: "Manage OLMv1 extensions and catalogs", + Long: "Manage OLMv1 resources like clusterextensions and clustercatalogs from the command line.", } getCmd := &cobra.Command{ diff --git a/internal/pkg/v1/action/catalog_create.go b/internal/pkg/v1/action/catalog_create.go index 06d684a..c286ee0 100644 --- a/internal/pkg/v1/action/catalog_create.go +++ b/internal/pkg/v1/action/catalog_create.go @@ -14,10 +14,10 @@ import ( ) type CatalogCreate struct { - config *action.Configuration - CatalogName string - ImageSourceRef string + config *action.Configuration + CatalogName string + ImageSourceRef string Priority int32 PollIntervalMinutes int Labels map[string]string @@ -26,8 +26,7 @@ type CatalogCreate struct { DryRun string Output string - - Logf func(string, ...interface{}) + Logf func(string, ...interface{}) } func NewCatalogCreate(config *action.Configuration) *CatalogCreate { diff --git a/internal/pkg/v1/action/catalog_delete.go b/internal/pkg/v1/action/catalog_delete.go index 66b0081..153091d 100644 --- a/internal/pkg/v1/action/catalog_delete.go +++ b/internal/pkg/v1/action/catalog_delete.go @@ -14,12 +14,12 @@ import ( type CatalogDelete struct { config *action.Configuration CatalogName string - DeleteAll bool - Logf func(string, ...interface{}) + DeleteAll bool DryRun string Output string + Logf func(string, ...interface{}) } func NewCatalogDelete(cfg *action.Configuration) *CatalogDelete { @@ -29,21 +29,21 @@ func NewCatalogDelete(cfg *action.Configuration) *CatalogDelete { } } -func (cd *CatalogDelete) Run(ctx context.Context) ([]olmv1.ClusterCatalog, error) { +func (i *CatalogDelete) Run(ctx context.Context) ([]olmv1.ClusterCatalog, error) { // validate - if cd.DeleteAll && cd.CatalogName != "" { + if i.DeleteAll && i.CatalogName != "" { return nil, ErrNameAndSelector } // delete single, specified catalog - if !cd.DeleteAll { - obj, err := cd.deleteCatalog(ctx, cd.CatalogName) + if !i.DeleteAll { + obj, err := i.deleteCatalog(ctx, i.CatalogName) return []olmv1.ClusterCatalog{obj}, err } // delete all existing catalogs var catatalogList olmv1.ClusterCatalogList - if err := cd.config.Client.List(ctx, &catatalogList); err != nil { + if err := i.config.Client.List(ctx, &catatalogList); err != nil { return nil, err } if len(catatalogList.Items) == 0 { @@ -53,7 +53,7 @@ func (cd *CatalogDelete) Run(ctx context.Context) ([]olmv1.ClusterCatalog, error errs := make([]error, 0, len(catatalogList.Items)) result := []olmv1.ClusterCatalog{} for _, catalog := range catatalogList.Items { - if obj, err := cd.deleteCatalog(ctx, catalog.Name); err != nil { + if obj, err := i.deleteCatalog(ctx, catalog.Name); err != nil { errs = append(errs, fmt.Errorf("failed deleting catalog %q: %w", catalog.Name, err)) } else { result = append(result, obj) @@ -63,17 +63,17 @@ func (cd *CatalogDelete) Run(ctx context.Context) ([]olmv1.ClusterCatalog, error return result, errors.Join(errs...) } -func (cd *CatalogDelete) deleteCatalog(ctx context.Context, name string) (olmv1.ClusterCatalog, error) { +func (i *CatalogDelete) deleteCatalog(ctx context.Context, name string) (olmv1.ClusterCatalog, error) { op := &olmv1.ClusterCatalog{} op.SetName(name) - if cd.DryRun == DryRunAll { - err := cd.config.Client.Delete(ctx, op, client.DryRunAll) + if i.DryRun == DryRunAll { + err := i.config.Client.Delete(ctx, op, client.DryRunAll) return *op, err } - if err := cd.config.Client.Delete(ctx, op); err != nil { + if err := i.config.Client.Delete(ctx, op); err != nil { return *op, err } - return *op, waitForDeletion(ctx, cd.config.Client, op) + return *op, waitForDeletion(ctx, i.config.Client, op) } diff --git a/internal/pkg/v1/action/catalog_get.go b/internal/pkg/v1/action/catalog_get.go index c3c243f..0333acf 100644 --- a/internal/pkg/v1/action/catalog_get.go +++ b/internal/pkg/v1/action/catalog_get.go @@ -2,7 +2,6 @@ package action import ( "context" - "fmt" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" @@ -16,7 +15,6 @@ import ( type CatalogInstalledGet struct { config *action.Configuration CatalogName string - Selector labels.Selector Selector string @@ -47,8 +45,12 @@ func (i *CatalogInstalledGet) Run(ctx context.Context) ([]olmv1.ClusterCatalog, // list var result olmv1.ClusterCatalogList listOpts := &client.ListOptions{} - if i.Selector != nil { - listOpts.LabelSelector = i.Selector + if len(i.Selector) > 0 { + selector, err := labels.Parse(i.Selector) + if err != nil { + return nil, err + } + listOpts.LabelSelector = selector } err := i.config.Client.List(ctx, &result, listOpts) diff --git a/internal/pkg/v1/action/catalog_search.go b/internal/pkg/v1/action/catalog_search.go index d5ca1ae..8a27912 100644 --- a/internal/pkg/v1/action/catalog_search.go +++ b/internal/pkg/v1/action/catalog_search.go @@ -1,7 +1,7 @@ package action import ( - "contz" + "context" "fmt" "time" @@ -16,8 +16,9 @@ import ( ) type CatalogSearch struct { - config *action.Configuration - CatalogName string + config *action.Configuration + CatalogName string + OutputFormat string Selector string ListVersions bool diff --git a/internal/pkg/v1/action/catalog_search_test.go b/internal/pkg/v1/action/catalog_search_test.go new file mode 100644 index 0000000..3ed1705 --- /dev/null +++ b/internal/pkg/v1/action/catalog_search_test.go @@ -0,0 +1,109 @@ +package action_test + +// import ( + +// . "github.com/onsi/ginkgo" +// . "github.com/onsi/gomega" + +// "fmt" +// "time" + +// v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" +// "github.com/operator-framework/kubectl-operator/pkg/action" +// olmv1 "github.com/operator-framework/operator-controller/api/v1" +// corev1 "k8s.io/api/core/v1" +// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +// "k8s.io/apimachinery/pkg/util/intstr" +// "k8s.io/client-go/rest" +// "sigs.k8s.io/controller-runtime/pkg/client/fake" +// ) + +// var _ = Describe("", func() { +// catalogdNamespace := "test" +// var serviceName, serviceNamespace, podName, catalogName string +// var servicePort, podPort int32 +// var serverHost, serverPort string + +// catalog := olmv1.ClusterCatalog{ +// Status: olmv1.ClusterCatalogStatus{ +// Conditions: []metav1.Condition{{ +// Type: olmv1.TypeServing, +// Status: metav1.ConditionTrue, +// }}, +// URLs: &olmv1.ClusterCatalogURLs{ +// Base: fmt.Sprintf("http://%s.%s:%d", serviceName, serviceNamespace, servicePort), //port optional if scheme present +// }, +// }, +// } +// secret := corev1.Secret{ +// Data: map[string][]byte{ +// "ca.crt": []byte{},//AppendCertsFromPEM +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "catalogd-*", +// Namespace: catalogdNamespace, +// }, +// } +// svc := corev1.Service{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: serviceName, +// Namespace: serviceNamespace, +// }, +// Spec: corev1.ServiceSpec{ +// Ports: []corev1.ServicePort{{ +// Port: int32(servicePort), +// TargetPort: intstr.IntOrString{IntVal: podPort}, +// }}, +// }, +// } +// endpoints := corev1.Endpoints{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: serviceName, +// Namespace: serviceNamespace, +// }, +// Subsets: []corev1.EndpointSubset{{ +// Addresses: []corev1.EndpointAddress{{ +// TargetRef: &corev1.ObjectReference{ +// Name: fmt.Sprintf("%s", podName), +// }, +// }}, +// }}, +// } +// scheme, err := action.NewScheme() +// Expect(err).ShouldNot(HaveOccurred()) +// fakeClientBuilder := fake.NewClientBuilder() +// fakeClientBuilder.WithScheme(scheme) +// fakeClientBuilder.WithObjects(&catalog, &secret, &svc, &endpoints) +// cfg := &action.Configuration { +// Config: &rest.Config{ +// Host: "localhost", +// APIPath: "", +// Timeout: 1*time.Minute, +// TLSClientConfig: rest.TLSClientConfig{ +// ServerName: "", +// NextProtos: []string{}, +// CAData: []byte{}, //certData, keyData not here? +// }, + +// }, +// Client: fakeClientBuilder.Build(), +// Scheme: scheme, +// } +// searchCmd := v1action.NewCatalogSearch(cfg) +// searchCmd.Timeout = "1m" +// searchCmd.CatalogName = catalogName +// BeforeEach(func(){ + +// }) +// It("", func() { +// Expect("") +// }) +// // server: localhost: fmt.Sprintf("%s/api/v1/namespaces/%s/pods/%s/portforward", c.cfg.Host, namespace, podName); +// // ports: []string{fmt.Sprintf("0:%d", podPort)}, +// // protocol := resp.Header.Get(httpstream.HeaderProtocolVersion) //must equal PortForwardProtocolV1Name + +// }) + +// func newServer(host string, port int) { + +// } diff --git a/internal/pkg/v1/action/catalog_update.go b/internal/pkg/v1/action/catalog_update.go index 98d8609..2d3e81f 100644 --- a/internal/pkg/v1/action/catalog_update.go +++ b/internal/pkg/v1/action/catalog_update.go @@ -24,10 +24,9 @@ type CatalogUpdate struct { ImageRef string IgnoreUnset bool - Logf func(string, ...interface{}) - DryRun string Output string + Logf func(string, ...interface{}) } func NewCatalogUpdate(config *action.Configuration) *CatalogUpdate { @@ -37,15 +36,15 @@ func NewCatalogUpdate(config *action.Configuration) *CatalogUpdate { } } -func (cu *CatalogUpdate) Run(ctx context.Context) (*olmv1.ClusterCatalog, error) { +func (i *CatalogUpdate) Run(ctx context.Context) (*olmv1.ClusterCatalog, error) { var catalog olmv1.ClusterCatalog var err error cuKey := types.NamespacedName{ - Name: cu.CatalogName, - Namespace: cu.config.Namespace, + Name: i.CatalogName, + Namespace: i.config.Namespace, } - if err = cu.config.Client.Get(ctx, cuKey, &catalog); err != nil { + if err = i.config.Client.Get(ctx, cuKey, &catalog); err != nil { return nil, err } @@ -53,36 +52,36 @@ func (cu *CatalogUpdate) Run(ctx context.Context) (*olmv1.ClusterCatalog, error) return nil, fmt.Errorf("unrecognized source type: %q", catalog.Spec.Source.Type) } - if cu.ImageRef != "" && !isValidImageRef(cu.ImageRef) { - return nil, fmt.Errorf("invalid image reference: %q, it must be a valid image reference format", cu.ImageRef) + if i.ImageRef != "" && !isValidImageRef(i.ImageRef) { + return nil, fmt.Errorf("invalid image reference: %q, it must be a valid image reference format", i.ImageRef) } - cu.setDefaults(&catalog) + i.setDefaults(&catalog) - cu.setUpdatedCatalog(&catalog) - if cu.DryRun == DryRunAll { - if err := cu.config.Client.Update(ctx, &catalog, client.DryRunAll); err != nil { + i.setUpdatedCatalog(&catalog) + if i.DryRun == DryRunAll { + if err := i.config.Client.Update(ctx, &catalog, client.DryRunAll); err != nil { return nil, err } return &catalog, nil } - if err := cu.config.Client.Update(ctx, &catalog); err != nil { + if err := i.config.Client.Update(ctx, &catalog); err != nil { return nil, err } - cu.Logf("Updating catalog %q in namespace %q", cu.CatalogName, cu.config.Namespace) + i.Logf("Updating catalog %q in namespace %q", i.CatalogName, i.config.Namespace) return &catalog, nil } -func (cu *CatalogUpdate) setUpdatedCatalog(catalog *olmv1.ClusterCatalog) { +func (i *CatalogUpdate) setUpdatedCatalog(catalog *olmv1.ClusterCatalog) { existingLabels := catalog.GetLabels() if existingLabels == nil { existingLabels = make(map[string]string) } - if cu.Labels != nil { - for k, v := range cu.Labels { + if i.Labels != nil { + for k, v := range i.Labels { if v == "" { delete(existingLabels, k) } else { @@ -92,54 +91,54 @@ func (cu *CatalogUpdate) setUpdatedCatalog(catalog *olmv1.ClusterCatalog) { catalog.SetLabels(existingLabels) } - if cu.Priority != nil { - catalog.Spec.Priority = *cu.Priority + if i.Priority != nil { + catalog.Spec.Priority = *i.Priority } if catalog.Spec.Source.Image == nil { catalog.Spec.Source.Image = &olmv1.ImageSource{} } - if cu.PollIntervalMinutes != nil { - if *cu.PollIntervalMinutes == 0 || *cu.PollIntervalMinutes == -1 { + if i.PollIntervalMinutes != nil { + if *i.PollIntervalMinutes == 0 || *i.PollIntervalMinutes == -1 { catalog.Spec.Source.Image.PollIntervalMinutes = nil } else { - catalog.Spec.Source.Image.PollIntervalMinutes = cu.PollIntervalMinutes + catalog.Spec.Source.Image.PollIntervalMinutes = i.PollIntervalMinutes } } - if cu.ImageRef != "" { - catalog.Spec.Source.Image.Ref = cu.ImageRef + if i.ImageRef != "" { + catalog.Spec.Source.Image.Ref = i.ImageRef } - if cu.AvailabilityMode != "" { - catalog.Spec.AvailabilityMode = olmv1.AvailabilityMode(cu.AvailabilityMode) + if i.AvailabilityMode != "" { + catalog.Spec.AvailabilityMode = olmv1.AvailabilityMode(i.AvailabilityMode) } } -func (cu *CatalogUpdate) setDefaults(catalog *olmv1.ClusterCatalog) { - if !cu.IgnoreUnset { +func (i *CatalogUpdate) setDefaults(catalog *olmv1.ClusterCatalog) { + if !i.IgnoreUnset { return } catalogSrc := catalog.Spec.Source - if cu.Priority == nil { - cu.Priority = &catalog.Spec.Priority + if i.Priority == nil { + i.Priority = &catalog.Spec.Priority } - if cu.PollIntervalMinutes == nil && catalogSrc.Image != nil && catalogSrc.Image.PollIntervalMinutes != nil { - cu.PollIntervalMinutes = catalogSrc.Image.PollIntervalMinutes + if i.PollIntervalMinutes == nil && catalogSrc.Image != nil && catalogSrc.Image.PollIntervalMinutes != nil { + i.PollIntervalMinutes = catalogSrc.Image.PollIntervalMinutes } - if cu.ImageRef == "" && catalogSrc.Image != nil { - cu.ImageRef = catalogSrc.Image.Ref + if i.ImageRef == "" && catalogSrc.Image != nil { + i.ImageRef = catalogSrc.Image.Ref } - if cu.AvailabilityMode == "" { - cu.AvailabilityMode = string(catalog.Spec.AvailabilityMode) + if i.AvailabilityMode == "" { + i.AvailabilityMode = string(catalog.Spec.AvailabilityMode) } - if len(cu.Labels) == 0 { - cu.Labels = catalog.Labels + if len(i.Labels) == 0 { + i.Labels = catalog.Labels } } diff --git a/internal/pkg/v1/action/extension_delete.go b/internal/pkg/v1/action/extension_delete.go index 40a4118..154c325 100644 --- a/internal/pkg/v1/action/extension_delete.go +++ b/internal/pkg/v1/action/extension_delete.go @@ -15,11 +15,12 @@ import ( type ExtensionDeletion struct { config *action.Configuration ExtensionName string - DeleteAll bool - Logf func(string, ...interface{}) + + DeleteAll bool DryRun string Output string + Logf func(string, ...interface{}) } // NewExtensionDelete creates a new ExtensionDeletion action @@ -32,42 +33,42 @@ func NewExtensionDelete(cfg *action.Configuration) *ExtensionDeletion { } } -func (u *ExtensionDeletion) Run(ctx context.Context) ([]olmv1.ClusterExtension, error) { - if u.DeleteAll && u.ExtensionName != "" { +func (i *ExtensionDeletion) Run(ctx context.Context) ([]olmv1.ClusterExtension, error) { + if i.DeleteAll && i.ExtensionName != "" { return nil, fmt.Errorf("cannot specify both --all and an extension name") } - if !u.DeleteAll { - ext, err := u.deleteExtension(ctx, u.ExtensionName) + if !i.DeleteAll { + ext, err := i.deleteExtension(ctx, i.ExtensionName) return []olmv1.ClusterExtension{ext}, err } // delete all existing extensions - return u.deleteAllExtensions(ctx) + return i.deleteAllExtensions(ctx) } // deleteExtension deletes a single extension in the cluster -func (u *ExtensionDeletion) deleteExtension(ctx context.Context, extName string) (olmv1.ClusterExtension, error) { +func (i *ExtensionDeletion) deleteExtension(ctx context.Context, extName string) (olmv1.ClusterExtension, error) { op := &olmv1.ClusterExtension{} op.SetName(extName) op.SetGroupVersionKind(olmv1.GroupVersion.WithKind("ClusterExtension")) - if u.DryRun == DryRunAll { - err := u.config.Client.Delete(ctx, op, client.DryRunAll) + if i.DryRun == DryRunAll { + err := i.config.Client.Delete(ctx, op, client.DryRunAll) return *op, err } - err := u.config.Client.Delete(ctx, op) + err := i.config.Client.Delete(ctx, op) if err != nil { return *op, err } // wait for deletion - return *op, waitForDeletion(ctx, u.config.Client, op) + return *op, waitForDeletion(ctx, i.config.Client, op) } // deleteAllExtensions deletes all extensions in the cluster -func (u *ExtensionDeletion) deleteAllExtensions(ctx context.Context) ([]olmv1.ClusterExtension, error) { +func (i *ExtensionDeletion) deleteAllExtensions(ctx context.Context) ([]olmv1.ClusterExtension, error) { var extensionList olmv1.ClusterExtensionList - if err := u.config.Client.List(ctx, &extensionList); err != nil { + if err := i.config.Client.List(ctx, &extensionList); err != nil { return nil, err } if len(extensionList.Items) == 0 { @@ -76,7 +77,7 @@ func (u *ExtensionDeletion) deleteAllExtensions(ctx context.Context) ([]olmv1.Cl errs := make([]error, 0, len(extensionList.Items)) result := []olmv1.ClusterExtension{} for _, extension := range extensionList.Items { - if op, err := u.deleteExtension(ctx, extension.Name); err != nil { + if op, err := i.deleteExtension(ctx, extension.Name); err != nil { errs = append(errs, fmt.Errorf("failed deleting extension %q: %w", extension.Name, err)) } else { result = append(result, op) diff --git a/internal/pkg/v1/action/extension_get.go b/internal/pkg/v1/action/extension_get.go index c52407c..49c758e 100644 --- a/internal/pkg/v1/action/extension_get.go +++ b/internal/pkg/v1/action/extension_get.go @@ -15,7 +15,8 @@ import ( type ExtensionInstalledGet struct { config *action.Configuration ExtensionName string - Selector labels.Selector + + Selector labels.Selector Logf func(string, ...interface{}) } diff --git a/internal/pkg/v1/action/extension_install.go b/internal/pkg/v1/action/extension_install.go index 4c57b45..c533082 100644 --- a/internal/pkg/v1/action/extension_install.go +++ b/internal/pkg/v1/action/extension_install.go @@ -17,23 +17,24 @@ import ( ) type ExtensionInstall struct { - config *action.Configuration - ExtensionName string - Namespace NamespaceConfig - PackageName string - Channels []string - Version string - ServiceAccount string - CleanupTimeout time.Duration - Logf func(string, ...interface{}) + config *action.Configuration + ExtensionName string - DryRun string - Output string + Namespace NamespaceConfig + PackageName string + Channels []string + Version string CatalogSelector *metav1.LabelSelector + ServiceAccount string + CleanupTimeout time.Duration UpgradeConstraintPolicy string PreflightCRDUpgradeSafetyEnforcement string CRDUpgradeSafetyEnforcement string Labels map[string]string + + DryRun string + Output string + Logf func(string, ...interface{}) } type NamespaceConfig struct { Name string @@ -73,7 +74,13 @@ func (i *ExtensionInstall) buildClusterExtension() olmv1.ClusterExtension { extension.Spec.Source.Catalog.UpgradeConstraintPolicy = olmv1.UpgradeConstraintPolicy(i.UpgradeConstraintPolicy) } if len(i.CRDUpgradeSafetyEnforcement) > 0 { - extension.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(i.CRDUpgradeSafetyEnforcement) + extension.Spec.Install = &olmv1.ClusterExtensionInstallConfig{ + Preflight: &olmv1.PreflightConfig{ + CRDUpgradeSafety: &olmv1.CRDUpgradeSafetyPreflightConfig{ + Enforcement: olmv1.CRDUpgradeSafetyEnforcement(i.CRDUpgradeSafetyEnforcement), + }, + }, + } } return extension @@ -99,6 +106,7 @@ func (i *ExtensionInstall) Run(ctx context.Context) (*olmv1.ClusterExtension, er } clusterExtension, err := i.waitForExtensionInstall(ctx) if err != nil { + i.Logf("failed to install extension %s: %w; cleaning up extension", i.PackageName, err) cleanupCtx, cancelCleanup := context.WithTimeout(context.Background(), i.CleanupTimeout) defer cancelCleanup() cleanupErr := i.cleanup(cleanupCtx) diff --git a/internal/pkg/v1/action/extension_update.go b/internal/pkg/v1/action/extension_update.go index 3c6f0f0..988714d 100644 --- a/internal/pkg/v1/action/extension_update.go +++ b/internal/pkg/v1/action/extension_update.go @@ -18,8 +18,7 @@ import ( ) type ExtensionUpdate struct { - config *action.Configuration - + config *action.Configuration ExtensionName string Version string @@ -32,13 +31,12 @@ type ExtensionUpdate struct { Labels map[string]string IgnoreUnset bool - CleanupTimeout time.Duration - - Logf func(string, ...interface{}) - + CleanupTimeout time.Duration CRDUpgradeSafetyEnforcement string - DryRun string - Output string + + DryRun string + Output string + Logf func(string, ...interface{}) } func NewExtensionUpdate(cfg *action.Configuration) *ExtensionUpdate { @@ -48,12 +46,12 @@ func NewExtensionUpdate(cfg *action.Configuration) *ExtensionUpdate { } } -func (ou *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, error) { +func (i *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, error) { var ext olmv1.ClusterExtension var err error - opKey := types.NamespacedName{Name: ou.ExtensionName} - if err = ou.config.Client.Get(ctx, opKey, &ext); err != nil { + opKey := types.NamespacedName{Name: i.ExtensionName} + if err = i.config.Client.Get(ctx, opKey, &ext); err != nil { return nil, err } @@ -61,51 +59,51 @@ func (ou *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, er return nil, fmt.Errorf("unrecognized source type: %q", ext.Spec.Source.SourceType) } - ou.setDefaults(ext) + i.setDefaults(ext) - if ou.Version != "" { - if _, err = semver.ParseRange(ou.Version); err != nil { + if i.Version != "" { + if _, err = semver.ParseRange(i.Version); err != nil { return nil, fmt.Errorf("failed parsing version: %w", err) } } - if ou.Selector != "" && ou.parsedSelector == nil { - ou.parsedSelector, err = metav1.ParseToLabelSelector(ou.Selector) + if i.Selector != "" && i.parsedSelector == nil { + i.parsedSelector, err = metav1.ParseToLabelSelector(i.Selector) if err != nil { return nil, fmt.Errorf("failed parsing selector: %w", err) } } - constraintPolicy := olmv1.UpgradeConstraintPolicy(ou.UpgradeConstraintPolicy) - if !ou.needsUpdate(ext, constraintPolicy) { + constraintPolicy := olmv1.UpgradeConstraintPolicy(i.UpgradeConstraintPolicy) + if !i.needsUpdate(ext, constraintPolicy) { return nil, ErrNoChange } - ou.prepareUpdatedExtension(&ext, constraintPolicy) - if ou.DryRun == DryRunAll { - if err := ou.config.Client.Update(ctx, &ext, client.DryRunAll); err != nil { + i.prepareUpdatedExtension(&ext, constraintPolicy) + if i.DryRun == DryRunAll { + if err := i.config.Client.Update(ctx, &ext, client.DryRunAll); err != nil { return nil, err } return &ext, nil } - if err := ou.config.Client.Update(ctx, &ext); err != nil { + if err := i.config.Client.Update(ctx, &ext); err != nil { return nil, err } - if err := waitUntilExtensionStatusCondition(ctx, ou.config.Client, &ext, olmv1.TypeInstalled, metav1.ConditionTrue); err != nil { + if err := waitUntilExtensionStatusCondition(ctx, i.config.Client, &ext, olmv1.TypeInstalled, metav1.ConditionTrue); err != nil { return nil, fmt.Errorf("timed out waiting for extension: %w", err) } return &ext, nil } -func (ou *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { - if !ou.IgnoreUnset { - if ou.UpgradeConstraintPolicy == "" { - ou.UpgradeConstraintPolicy = string(olmv1.UpgradeConstraintPolicyCatalogProvided) +func (i *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { + if !i.IgnoreUnset { + if i.UpgradeConstraintPolicy == "" { + i.UpgradeConstraintPolicy = string(olmv1.UpgradeConstraintPolicyCatalogProvided) } - if ou.CRDUpgradeSafetyEnforcement == "" { - ou.CRDUpgradeSafetyEnforcement = string(olmv1.CRDUpgradeSafetyEnforcementStrict) + if i.CRDUpgradeSafetyEnforcement == "" { + i.CRDUpgradeSafetyEnforcement = string(olmv1.CRDUpgradeSafetyEnforcementStrict) } return @@ -114,41 +112,41 @@ func (ou *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { // IgnoreUnset is enabled // set all unset values to what they are on the current object catalogSrc := ext.Spec.Source.Catalog - if ou.Version == "" { - ou.Version = catalogSrc.Version + if i.Version == "" { + i.Version = catalogSrc.Version } - if len(ou.Channels) == 0 { - ou.Channels = catalogSrc.Channels + if len(i.Channels) == 0 { + i.Channels = catalogSrc.Channels } - if ou.UpgradeConstraintPolicy == "" { - ou.UpgradeConstraintPolicy = string(catalogSrc.UpgradeConstraintPolicy) + if i.UpgradeConstraintPolicy == "" { + i.UpgradeConstraintPolicy = string(catalogSrc.UpgradeConstraintPolicy) } - if ou.CRDUpgradeSafetyEnforcement == "" { - ou.CRDUpgradeSafetyEnforcement = string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) + if i.CRDUpgradeSafetyEnforcement == "" { + i.CRDUpgradeSafetyEnforcement = string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) } - if len(ou.Labels) == 0 { - ou.Labels = ext.Labels + if len(i.Labels) == 0 { + i.Labels = ext.Labels } - if ou.Selector == "" && catalogSrc.Selector != nil { - ou.parsedSelector = catalogSrc.Selector + if i.Selector == "" && catalogSrc.Selector != nil { + i.parsedSelector = catalogSrc.Selector } } -func (ou *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) bool { +func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) bool { catalogSrc := ext.Spec.Source.Catalog // object string form is used for comparison to: // - remove the need for potentially costly metav1.FormatLabelSelector calls // - avoid having to handle potential reordering of items from on cluster state - sameSelectors := (catalogSrc.Selector == nil && ou.parsedSelector == nil) || - (catalogSrc.Selector != nil && ou.parsedSelector != nil && - catalogSrc.Selector.String() == ou.parsedSelector.String()) + sameSelectors := (catalogSrc.Selector == nil && i.parsedSelector == nil) || + (catalogSrc.Selector != nil && i.parsedSelector != nil && + catalogSrc.Selector.String() == i.parsedSelector.String()) - if catalogSrc.Version == ou.Version && - slices.Equal(catalogSrc.Channels, ou.Channels) && + if catalogSrc.Version == i.Version && + slices.Equal(catalogSrc.Channels, i.Channels) && catalogSrc.UpgradeConstraintPolicy == constraintPolicy && - maps.Equal(ext.Labels, ou.Labels) && - string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) == ou.CRDUpgradeSafetyEnforcement && + maps.Equal(ext.Labels, i.Labels) && + string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) == i.CRDUpgradeSafetyEnforcement && sameSelectors { return false } @@ -156,11 +154,11 @@ func (ou *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPol return true } -func (ou *ExtensionUpdate) prepareUpdatedExtension(ext *olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) { - ext.SetLabels(ou.Labels) - ext.Spec.Source.Catalog.Version = ou.Version - ext.Spec.Source.Catalog.Selector = ou.parsedSelector - ext.Spec.Source.Catalog.Channels = ou.Channels +func (i *ExtensionUpdate) prepareUpdatedExtension(ext *olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) { + ext.SetLabels(i.Labels) + ext.Spec.Source.Catalog.Version = i.Version + ext.Spec.Source.Catalog.Selector = i.parsedSelector + ext.Spec.Source.Catalog.Channels = i.Channels ext.Spec.Source.Catalog.UpgradeConstraintPolicy = constraintPolicy - ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(ou.CRDUpgradeSafetyEnforcement) + ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(i.CRDUpgradeSafetyEnforcement) } diff --git a/internal/pkg/v1/action/helpers.go b/internal/pkg/v1/action/helpers.go index 85e32d0..ac75835 100644 --- a/internal/pkg/v1/action/helpers.go +++ b/internal/pkg/v1/action/helpers.go @@ -34,6 +34,7 @@ func waitUntilCatalogStatusCondition( conditionType string, conditionStatus metav1.ConditionStatus, ) error { + fmt.Printf("waiting for ClusterCatalog %s to become healthy...\n", catalog.Name) s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) s.Start() defer s.Stop() @@ -60,6 +61,7 @@ func waitUntilExtensionStatusCondition( conditionStatus metav1.ConditionStatus, ) error { s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Prefix = fmt.Sprintf("waiting for ClusterExtension %s to become healthy...", extension.Name) s.Start() defer s.Stop() opKey := objectKeyForObject(extension) @@ -79,6 +81,7 @@ func waitUntilExtensionStatusCondition( func deleteWithTimeout(cl deleter, obj client.Object, timeout time.Duration) error { s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Prefix = fmt.Sprintf("deleting %s...", obj.GetObjectKind().GroupVersionKind().Kind) s.Start() defer s.Stop() ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -93,6 +96,7 @@ func deleteWithTimeout(cl deleter, obj client.Object, timeout time.Duration) err func waitForDeletion(ctx context.Context, cl getter, objs ...client.Object) error { s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) + s.Prefix = fmt.Sprintf("waiting for delete %s...", objs[0].GetObjectKind().GroupVersionKind().Kind) s.Start() defer s.Stop() for _, obj := range objs { From 1900b43370fd908b1bf008ffb6fbb2fe63a7399c Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Tue, 25 Nov 2025 02:29:39 -0500 Subject: [PATCH 09/11] group common flags Signed-off-by: Ankita Thomas --- go.mod | 2 +- internal/cmd/internal/olmv1/catalog_create.go | 37 +++- internal/cmd/internal/olmv1/catalog_delete.go | 39 ++-- internal/cmd/internal/olmv1/catalog_search.go | 18 +- internal/cmd/internal/olmv1/catalog_update.go | 65 +++--- .../cmd/internal/olmv1/extension_delete.go | 39 ++-- .../cmd/internal/olmv1/extension_install.go | 69 +++--- .../cmd/internal/olmv1/extension_update.go | 45 ++-- internal/cmd/internal/olmv1/flags.go | 132 +++++++++++- internal/pkg/v1/action/catalog_create.go | 6 +- internal/pkg/v1/action/catalog_update.go | 11 +- internal/pkg/v1/action/extension_update.go | 34 +-- olmv1.md | 200 ++++++++++++++---- 13 files changed, 491 insertions(+), 206 deletions(-) diff --git a/go.mod b/go.mod index 1cf127d..4c3f374 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( k8s.io/apimachinery v0.33.4 k8s.io/cli-runtime v0.33.3 k8s.io/client-go v0.33.4 + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/yaml v1.6.0 ) @@ -136,7 +137,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect diff --git a/internal/cmd/internal/olmv1/catalog_create.go b/internal/cmd/internal/olmv1/catalog_create.go index 6bf8523..4a56dd1 100644 --- a/internal/cmd/internal/olmv1/catalog_create.go +++ b/internal/cmd/internal/olmv1/catalog_create.go @@ -12,12 +12,19 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" ) +type catalogCreateOptions struct { + mutableCatalogOptions + dryRunOptions +} + // NewCatalogCreateCmd allows creating a new catalog func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogCreate(cfg) i.Logf = log.Printf + var opts catalogCreateOptions cmd := &cobra.Command{ Use: "catalog ", @@ -27,10 +34,12 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { i.CatalogName = args[0] i.ImageSourceRef = args[1] - if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { - log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + opts.Image = i.ImageSourceRef + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %s", err.Error()) } - + i.DryRun = opts.DryRun + i.Output = opts.Output catalogObj, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to create catalog %q: %v\n", i.CatalogName, err) @@ -50,17 +59,23 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { }, } bindCatalogCreateFlags(cmd.Flags(), i) + bindMutableCatalogFlags(cmd.Flags(), &opts.mutableCatalogOptions) + bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } func bindCatalogCreateFlags(fs *pflag.FlagSet, i *v1action.CatalogCreate) { - fs.Int32Var(&i.Priority, "priority", 0, "priority determines the likelihood of a catalog being selected in conflict scenarios") - fs.BoolVar(&i.Available, "available", true, "determines whether a catalog should be active and serving data. default: true, meaning new catalogs serve their contents by default.") - fs.IntVar(&i.PollIntervalMinutes, "source-poll-interval-minutes", 10, "catalog source polling interval [in minutes]") - fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new catalog") - fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") - // sigs.k8s.io/controller-runtime/pkg/client supported dry-run values only. - fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it if non-empty. One of: (All)") - fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") + fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt.") +} + +func (o *catalogCreateOptions) validate() error { + var errs []error + if err := o.dryRunOptions.validate(); err != nil { + errs = append(errs, err) + } + if err := o.mutableCatalogOptions.validate(); err != nil { + errs = append(errs, err) + } + return errors.NewAggregate(errs) } diff --git a/internal/cmd/internal/olmv1/catalog_delete.go b/internal/cmd/internal/olmv1/catalog_delete.go index 6b8f24d..d3911fe 100644 --- a/internal/cmd/internal/olmv1/catalog_delete.go +++ b/internal/cmd/internal/olmv1/catalog_delete.go @@ -12,11 +12,16 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +type catalogDeleteOptions struct { + dryRunOptions +} + // NewCatalogDeleteCmd allows deleting either a single or all // existing catalogs func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { - d := v1action.NewCatalogDelete(cfg) - d.Logf = log.Printf + i := v1action.NewCatalogDelete(cfg) + i.Logf = log.Printf + var opts catalogDeleteOptions cmd := &cobra.Command{ Use: "catalog [catalog_name]", @@ -25,46 +30,46 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { Short: "Delete either a single or all of the existing catalogs", Run: func(cmd *cobra.Command, args []string) { if len(args) > 0 { - if d.DeleteAll { + if i.DeleteAll { log.Fatalf("failed to delete catalog: cannot specify both --all and a catalog name") } - d.CatalogName = args[0] + i.CatalogName = args[0] + } + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %s", err.Error()) } - catalogs, err := d.Run(cmd.Context()) + i.DryRun = opts.DryRun + i.Output = opts.Output + catalogs, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to delete catalog(s): %v", err) } - - if len(d.DryRun) == 0 { + if len(i.DryRun) == 0 { for _, catn := range catalogs { log.Printf("catalog %s deleted", catn.Name) } return } - if len(d.Output) == 0 { + if len(i.Output) == 0 { for _, catn := range catalogs { log.Printf("catalog %s deleted (dry run)\n", catn.Name) } return } - for _, i := range catalogs { - i.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + for _, c := range catalogs { + c.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) } - printFormattedCatalogs(d.Output, catalogs...) - for _, catalog := range catalogs { - log.Printf("catalog %q deleted", catalog.Name) - } + printFormattedCatalogs(i.Output, catalogs...) }, } - bindCatalogDeleteFlags(cmd.Flags(), d) + bindCatalogDeleteFlags(cmd.Flags(), i) + bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } func bindCatalogDeleteFlags(fs *pflag.FlagSet, d *v1action.CatalogDelete) { fs.BoolVarP(&d.DeleteAll, "all", "a", false, "delete all catalogs") - fs.StringVar(&d.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&d.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/catalog_search.go b/internal/cmd/internal/olmv1/catalog_search.go index 2178690..16d0491 100644 --- a/internal/cmd/internal/olmv1/catalog_search.go +++ b/internal/cmd/internal/olmv1/catalog_search.go @@ -26,7 +26,7 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command { Use: "catalog", Aliases: []string{"catalogs"}, Args: cobra.RangeArgs(0, 1), - Short: "Search catalogs for installable operators matching parameters", + Short: "Search catalogs for installable packages matching parameters", Run: func(cmd *cobra.Command, args []string) { catalogContents, err := i.Run(cmd.Context()) if err != nil { @@ -40,7 +40,7 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command { case "yaml": printDeclCfgYAML(os.Stdout, catalogContents) default: - log.Fatalf("unsupported output format %s: allwed formats are (json|yaml|table)", i.OutputFormat) + log.Fatalf("unsupported output format %s: allowed formats are (json|yaml|table)", i.OutputFormat) } }, } @@ -50,13 +50,11 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command { } func bindCatalogSearchFlags(fs *pflag.FlagSet, i *v1action.CatalogSearch) { - fs.StringVar(&i.CatalogName, "catalog", "", "Catalog to search on. If not provided, all available catalogs are searched.") - fs.StringVarP(&i.Selector, "selector", "l", "", "Selector (label query) to filter catalogs on, supports '=', '==', and '!='") + fs.StringVar(&i.CatalogName, "catalog", "", "name of the catalog to search. If not provided, all available catalogs are searched.") + fs.StringVarP(&i.Selector, "selector", "l", "", "selector (label query) to filter catalogs on, supports '=', '==', and '!='") fs.StringVarP(&i.OutputFormat, "output", "o", "", "output format. One of: (yaml|json)") - fs.BoolVar(&i.ListVersions, "list-versions", false, "List all versions available for each package") - fs.StringVar(&i.Package, "package", "", "Search for package by name. If empty, all available packages will be listed") - fs.StringVar(&i.CatalogdNamespace, "catalogd-namespace", "olmv1-system", "Namespace for the catalogd controller") - fs.StringVar(&i.Timeout, "timeout", "5m", "Timeout for fetching catalog contents") - // installable vs uninstallable, all versions, channels - // fs.StringVar(&i.showAll, "image", "", "Image reference for the catalog source. Leave unset to retain the current image.") + fs.BoolVar(&i.ListVersions, "list-versions", false, "list all versions available for each package") + fs.StringVar(&i.Package, "package", "", "search for package by name. If empty, all available packages will be listed") + fs.StringVar(&i.CatalogdNamespace, "catalogd-namespace", "olmv1-system", "namespace for the catalogd controller") + fs.StringVar(&i.Timeout, "timeout", "5m", "timeout for fetching catalog contents") } diff --git a/internal/cmd/internal/olmv1/catalog_update.go b/internal/cmd/internal/olmv1/catalog_update.go index 37ba26b..e4838e8 100644 --- a/internal/cmd/internal/olmv1/catalog_update.go +++ b/internal/cmd/internal/olmv1/catalog_update.go @@ -2,6 +2,7 @@ package olmv1 import ( "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" @@ -9,17 +10,19 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" ) +type catalogUpdateOptions struct { + mutableCatalogOptions + dryRunOptions +} + // NewCatalogUpdateCmd allows updating a selected clustercatalog func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogUpdate(cfg) i.Logf = log.Printf - - var priority int32 - var pollInterval int - var labels map[string]string - var available string + var opts catalogUpdateOptions cmd := &cobra.Command{ Use: "catalog ", @@ -27,28 +30,21 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.CatalogName = args[0] + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %s", err.Error()) + } if cmd.Flags().Changed("priority") { - i.Priority = &priority + i.Priority = &opts.Priority } if cmd.Flags().Changed("source-poll-interval-minutes") { - i.PollIntervalMinutes = &pollInterval + i.PollIntervalMinutes = &opts.PollIntervalMinutes } if cmd.Flags().Changed("labels") { - i.Labels = labels - } - if len(available) > 0 { - switch available { - case "true": - i.AvailabilityMode = "Available" - case "false": - i.AvailabilityMode = "Unavailable" - default: - log.Fatalf("invalid value for `--available` %s; must be one of (true, false)\n", available) - } - } - if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { - log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + i.Labels = opts.Labels } + i.AvailabilityMode = opts.AvailabilityMode + i.DryRun = opts.DryRun + i.Output = opts.Output catalogObj, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to update catalog: %v", err) @@ -68,14 +64,25 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { printFormattedCatalogs(i.Output, *catalogObj) }, } - cmd.Flags().Int32Var(&priority, "priority", 0, "priority determines the likelihood of a catalog being selected in conflict scenarios") - cmd.Flags().StringVar(&available, "available", "", "determines whether a catalog should be active and serving data. default: true, meaning new catalogs serve their contents by default.") - cmd.Flags().IntVar(&pollInterval, "source-poll-interval-minutes", 5, "catalog source polling interval [in minutes]. Set to 0 or -1 to remove the polling interval.") - cmd.Flags().StringToStringVar(&labels, "labels", map[string]string{}, "labels that will be added to the catalog") - cmd.Flags().StringVar(&i.ImageRef, "image", "", "Image reference for the catalog source. Leave unset to retain the current image.") - cmd.Flags().BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead") - cmd.Flags().StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it if non-empty. One of: (All)") - cmd.Flags().StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") + bindCatalogUpdateFlags(cmd.Flags(), i) + bindMutableCatalogFlags(cmd.Flags(), &opts.mutableCatalogOptions) + bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } + +func bindCatalogUpdateFlags(fs *pflag.FlagSet, i *v1action.CatalogUpdate) { + fs.StringVar(&i.ImageRef, "image", "", "image reference for the catalog source. Leave unset to retain the current image.") + fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "set to false to revert all values not specifically set with flags in the command to their default as defined by the clustercatalog customresoucedefinition.") +} + +func (o *catalogUpdateOptions) validate() error { + var errs []error + if err := o.dryRunOptions.validate(); err != nil { + errs = append(errs, err) + } + if err := o.mutableCatalogOptions.validate(); err != nil { + errs = append(errs, err) + } + return errors.NewAggregate(errs) +} diff --git a/internal/cmd/internal/olmv1/extension_delete.go b/internal/cmd/internal/olmv1/extension_delete.go index 838a400..4a76fb2 100644 --- a/internal/cmd/internal/olmv1/extension_delete.go +++ b/internal/cmd/internal/olmv1/extension_delete.go @@ -12,9 +12,14 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +type extensionDeleteOptions struct { + dryRunOptions +} + func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { - e := v1action.NewExtensionDelete(cfg) - e.Logf = log.Printf + i := v1action.NewExtensionDelete(cfg) + i.Logf = log.Printf + var opts extensionDeleteOptions cmd := &cobra.Command{ Use: "extension [extension_name]", @@ -25,42 +30,46 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { cascades to the deletion of all operands.`, Args: cobra.RangeArgs(0, 1), Run: func(cmd *cobra.Command, args []string) { - if len(e.DryRun) > 0 && e.DryRun != v1action.DryRunAll { - log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", e.DryRun, v1action.DryRunAll) + if len(args) > 0 { + if i.DeleteAll { + log.Fatalf("failed to delete extension: cannot specify both --all and an extension name") + } + i.ExtensionName = args[0] } - if len(args) != 0 { - e.ExtensionName = args[0] + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %s", err.Error()) } - extensions, err := e.Run(cmd.Context()) + i.DryRun = opts.DryRun + i.Output = opts.Output + extensions, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to delete extension: %v", err) } - if len(e.DryRun) == 0 { + if len(i.DryRun) == 0 { for _, extn := range extensions { log.Printf("extension %s deleted", extn.Name) } return } - if len(e.Output) == 0 { + if len(i.Output) == 0 { for _, extn := range extensions { log.Printf("extension %s deleted (dry run)\n", extn.Name) } return } - for _, i := range extensions { - i.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, + for _, e := range extensions { + e.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) } - printFormattedExtensions(e.Output, extensions...) + printFormattedExtensions(i.Output, extensions...) }, } - bindExtensionDeleteFlags(cmd.Flags(), e) + bindExtensionDeleteFlags(cmd.Flags(), i) + bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } func bindExtensionDeleteFlags(fs *pflag.FlagSet, e *v1action.ExtensionDeletion) { fs.BoolVarP(&e.DeleteAll, "all", "a", false, "delete all extensions") - fs.StringVar(&e.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&e.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } diff --git a/internal/cmd/internal/olmv1/extension_install.go b/internal/cmd/internal/olmv1/extension_install.go index 68918df..3cf8df2 100644 --- a/internal/cmd/internal/olmv1/extension_install.go +++ b/internal/cmd/internal/olmv1/extension_install.go @@ -9,21 +9,21 @@ import ( "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" olmv1 "github.com/operator-framework/operator-controller/api/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" ) type extensionInstallOptions struct { - CatalogSelector string + dryRunOptions + mutableExtensionOptions } func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionInstall(cfg) i.Logf = log.Printf - var extentionInstallOpts extensionInstallOptions - var err error + var opts extensionInstallOptions cmd := &cobra.Command{ Use: "extension ", @@ -31,29 +31,20 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] - - if len(extentionInstallOpts.CatalogSelector) != 0 { - i.CatalogSelector, err = metav1.ParseToLabelSelector(extentionInstallOpts.CatalogSelector) - if err != nil { - log.Fatalf("unable to parse selector %s: %v", extentionInstallOpts.CatalogSelector, err) - } - } - switch i.UpgradeConstraintPolicy { - case "CatalogProvided", "SelfCertified", "": - default: - log.Fatalf("unrecognized Upgrade Constraint Policy %s, must be one of: (CatalogProvided|SelfCertified)", i.UpgradeConstraintPolicy) - } - switch i.CRDUpgradeSafetyEnforcement { - case "Strict", "None", "": - default: - log.Fatalf("unrecognized CRD Upgrade Safety Enforcement Policy %s, must be one of: (Strict|None)", i.CRDUpgradeSafetyEnforcement) - } - if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { - log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %s", err.Error()) } + i.Version = opts.Version + i.Channels = opts.Channels + i.Labels = opts.Labels + i.UpgradeConstraintPolicy = opts.UpgradeConstraintPolicy + i.CRDUpgradeSafetyEnforcement = opts.CRDUpgradeSafetyEnforcement + i.CatalogSelector = opts.ParsedSelector + i.DryRun = opts.DryRun + i.Output = opts.Output extObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to install extension %q: %w\n", i.ExtensionName, err) + log.Fatalf("failed to install extension %q: %s\n", i.ExtensionName, err.Error()) } if len(i.DryRun) == 0 { log.Printf("extension %q created\n", i.ExtensionName) @@ -70,25 +61,27 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { }, } - bindExtensionInstallFlags(cmd.Flags(), i, &extentionInstallOpts) + bindExtensionInstallFlags(cmd.Flags(), i) + bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) + bindMutableExtensionFlags(cmd.Flags(), &opts.mutableExtensionOptions) return cmd } -func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall, o *extensionInstallOptions) { +func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall) { fs.StringVarP(&i.Namespace.Name, "namespace", "n", "olmv1-system", "namespace to install the operator in") //infer? fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the operator to install. Required.") - fs.StringSliceVarP(&i.Channels, "channels", "c", []string{}, "channels to be used for getting updates e.g --channels \"stable,dev-preview,preview\"") - fs.StringVarP(&i.Version, "version", "v", "", "version (or version range) from which to resolve bundles") fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation") - fs.DurationVarP(&i.CleanupTimeout, "cleanup-timeout", "d", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") - fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new extension") - fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") - fs.StringVar(&o.CatalogSelector, "catalog-selector", "", "selector (label query) to filter catalogs to search for the package, "+ - "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ - "in (value3)). Matching objects must satisfy all of the specified label constraints.") - fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "CatalogProvided", "controls whether the upgrade path(s) defined in the catalog are enforced."+ - " One of CatalogProvided, SelfCertified), Default: CatalogProvided") - fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "Strict", "policy for preflight CRD Upgrade safety checks. One of: (Strict, None), default: Strict") + fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") +} + +func (o *extensionInstallOptions) validate() error { + var errs []error + if err := o.dryRunOptions.validate(); err != nil { + errs = append(errs, err) + } + if err := o.mutableExtensionOptions.validate(); err != nil { + errs = append(errs, err) + } + return errors.NewAggregate(errs) } diff --git a/internal/cmd/internal/olmv1/extension_update.go b/internal/cmd/internal/olmv1/extension_update.go index 1a4f65b..b63efc6 100644 --- a/internal/cmd/internal/olmv1/extension_update.go +++ b/internal/cmd/internal/olmv1/extension_update.go @@ -10,12 +10,19 @@ import ( olmv1 "github.com/operator-framework/operator-controller/api/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" ) +type extensionUpdateOptions struct { + dryRunOptions + mutableExtensionOptions +} + // NewExtensionUpdateCmd allows updating a selected operator func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionUpdate(cfg) i.Logf = log.Printf + var opts extensionUpdateOptions cmd := &cobra.Command{ Use: "extension ", @@ -23,9 +30,17 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] - if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll { - log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll) + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %s", err.Error()) } + i.Version = opts.Version + i.Channels = opts.Channels + i.Labels = opts.Labels + i.UpgradeConstraintPolicy = opts.UpgradeConstraintPolicy + i.CRDUpgradeSafetyEnforcement = opts.CRDUpgradeSafetyEnforcement + i.CatalogSelector = opts.ParsedSelector + i.DryRun = opts.DryRun + i.Output = opts.Output extObj, err := i.Run(cmd.Context()) if err != nil { log.Fatalf("failed to update extension: %v", err) @@ -45,21 +60,23 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { }, } bindExtensionUpdateFlags(cmd.Flags(), i) + bindMutableExtensionFlags(cmd.Flags(), &opts.mutableExtensionOptions) + bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } func bindExtensionUpdateFlags(fs *pflag.FlagSet, i *v1action.ExtensionUpdate) { - fs.StringArrayVar(&i.Channels, "channels", []string{}, "desired channels for extension versions. AND operation with version. Empty list means all available channels will be taken into consideration") - fs.StringVar(&i.Version, "version", "", "desired extension version (single or range) in semVer format. AND operation with channels") - fs.StringVar(&i.Selector, "catalog-selector", "", "selector (label query) to filter catalogs to search for the package, "+ - "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ - "in (value3)). Matching objects must satisfy all of the specified label constraints.") - fs.StringVar(&i.UpgradeConstraintPolicy, "upgrade-constraint-policy", "", "controls whether the upgrade path(s) defined in the catalog are enforced."+ - " One of CatalogProvided, SelfCertified), Default: CatalogProvided") - fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels that will be set on the extension") - fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead") - fs.StringVar(&i.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "", "policy for preflight CRD Upgrade safety checks. One of: (Strict, None), default: Strict") - fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") - fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") + fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "set to false to revert all values not specifically set with flags in the command to their default as defined by the clusterextension customresoucedefinition.") +} + +func (o *extensionUpdateOptions) validate() error { + var errs []error + if err := o.dryRunOptions.validate(); err != nil { + errs = append(errs, err) + } + if err := o.mutableExtensionOptions.validate(); err != nil { + errs = append(errs, err) + } + return errors.NewAggregate(errs) } diff --git a/internal/cmd/internal/olmv1/flags.go b/internal/cmd/internal/olmv1/flags.go index f6890a8..0478bcf 100644 --- a/internal/cmd/internal/olmv1/flags.go +++ b/internal/cmd/internal/olmv1/flags.go @@ -1,6 +1,18 @@ package olmv1 -import "github.com/spf13/pflag" +import ( + "fmt" + + "github.com/blang/semver/v4" + "github.com/containerd/containerd/reference" + "github.com/spf13/pflag" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/errors" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + + v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" +) type getOptions struct { Output string @@ -14,3 +26,121 @@ func bindGetFlags(fs *pflag.FlagSet, o *getOptions) { "in (value3)). Matching objects must satisfy all of the specified label constraints.") } + +type dryRunOptions struct { + DryRun string + Output string +} + +func bindDryRunFlags(fs *pflag.FlagSet, o *dryRunOptions) { + fs.StringVar(&o.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVarP(&o.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") +} + +func (o *dryRunOptions) validate() error { + var errs []error + if len(o.DryRun) > 0 && o.DryRun != v1action.DryRunAll { + errs = append(errs, fmt.Errorf("invalid value for `--dry-run` %s, must be one of (%s)", o.DryRun, v1action.DryRunAll)) + } + switch o.Output { + case "json", "yaml", "": + default: + errs = append(errs, fmt.Errorf("unrecognized output format %s: must be one of (json, yaml)", o.Output)) + } + return errors.NewAggregate(errs) +} + +type mutableExtensionOptions struct { + Channels []string + Version string + Labels map[string]string + UpgradeConstraintPolicy string + CRDUpgradeSafetyEnforcement string + CatalogSelector string + ParsedSelector *metav1.LabelSelector +} + +func bindMutableExtensionFlags(fs *pflag.FlagSet, o *mutableExtensionOptions) { + fs.StringSliceVarP(&o.Channels, "channels", "c", []string{}, "channels to be used for getting updates. If omitted, extension versions in all channels will be "+ + "considered for upgrades. When used with '--version', only package versions meeting both constraints will be considered.") + fs.StringVarP(&o.Version, "version", "v", "", "version (or version range) in semver format to limit the allowable package versions to. If used with '--channel', "+ + "only package versions meeting both constraints will be considered.") + fs.StringToStringVar(&o.Labels, "labels", map[string]string{}, "labels to add to the extension. Set a label's value as empty to remove that label") + fs.StringVar(&o.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "", fmt.Sprintf("policy for preflight CRD Upgrade safety checks. One of: %v, (default %s)", + []string{string(olmv1.CRDUpgradeSafetyEnforcementStrict), string(olmv1.CRDUpgradeSafetyEnforcementNone)}, olmv1.CRDUpgradeSafetyEnforcementStrict)) + fs.StringVar(&o.UpgradeConstraintPolicy, "upgrade-constraint-policy", "", "controls whether the package upgrade path(s) defined in the catalog are enforced."+ + fmt.Sprintf(" One of %v, (default %s)", []string{string(olmv1.UpgradeConstraintPolicyCatalogProvided), string(olmv1.UpgradeConstraintPolicySelfCertified)}, + olmv1.UpgradeConstraintPolicyCatalogProvided)) + fs.StringVarP(&o.CatalogSelector, "catalog-selector", "l", "", "selector (label query) to filter catalogs to search for the package, "+ + "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ + "in (value3)). Matching objects must satisfy all of the specified label constraints.") +} + +func (o mutableExtensionOptions) validate() error { + var errs []error + if len(o.Version) > 0 { + if _, err := semver.ParseRange(o.Version); err != nil { + errs = append(errs, fmt.Errorf("invalid `--version` %s: %v", o.Version, err)) + } + } + switch o.CRDUpgradeSafetyEnforcement { + case string(olmv1.CRDUpgradeSafetyEnforcementStrict), string(olmv1.CRDUpgradeSafetyEnforcementNone), "": + default: + errs = append(errs, fmt.Errorf("invalid `--crd-upgrade-safety-enforcement` %s: must be one of: %v", o.CRDUpgradeSafetyEnforcement, + []string{string(olmv1.CRDUpgradeSafetyEnforcementStrict), string(olmv1.CRDUpgradeSafetyEnforcementNone)})) + } + switch o.UpgradeConstraintPolicy { + case string(olmv1.UpgradeConstraintPolicyCatalogProvided), string(olmv1.UpgradeConstraintPolicySelfCertified), "": + default: + errs = append(errs, fmt.Errorf("invalid `--upgrade-constraint-policy` %s: must be one of: %v", o.UpgradeConstraintPolicy, + []string{string(olmv1.UpgradeConstraintPolicyCatalogProvided), string(olmv1.UpgradeConstraintPolicySelfCertified)})) + } + if len(o.CatalogSelector) > 0 { + var err error + o.ParsedSelector, err = metav1.ParseToLabelSelector(o.CatalogSelector) + if err != nil { + errs = append(errs, fmt.Errorf("invalid `--labels` value %s: %v", o.CatalogSelector, err)) + } + } + return errors.NewAggregate(errs) +} + +type mutableCatalogOptions struct { + Priority int32 + AvailabilityMode string + PollIntervalMinutes int + Labels map[string]string + Image string +} + +func bindMutableCatalogFlags(fs *pflag.FlagSet, o *mutableCatalogOptions) { + fs.Int32Var(&o.Priority, "priority", 0, "relative priority of the catalog among all on-cluster catalogs for installing or updating packages."+ + " A higher number equals greater priority; negative values indicate less priority than the default.") + fs.StringVar(&o.AvailabilityMode, "available", "", "determines whether a catalog should be active and serving data. Setting the flag to false "+ + "means the catalog will not serve its contents. Set to true by default for new catalogs.") + fs.IntVar(&o.PollIntervalMinutes, "source-poll-interval-minutes", 0, "the interval in minutes to poll the catalog's source image for new content."+ + " Only valid for tag based source image references. Set to 0 or -1 to disable polling.") + fs.StringToStringVar(&o.Labels, "labels", map[string]string{}, "labels to add to the catalog. Set a label's value as empty to remove it.") +} + +func (o mutableCatalogOptions) validate() error { + var errs []error + switch o.AvailabilityMode { + case "": + case "true": + o.AvailabilityMode = string(olmv1.AvailabilityModeAvailable) + case "false": + o.AvailabilityMode = string(olmv1.AvailabilityModeUnavailable) + default: + errs = append(errs, fmt.Errorf("invalid `--labels` value %s: must be one of: [true, false]", o.AvailabilityMode)) + } + if o.PollIntervalMinutes > 0 && len(o.Image) > 0 { + ref, err := reference.Parse(o.Image) + if err != nil { + errs = append(errs, fmt.Errorf("invalid catalog source image %s: %v", o.Image, err)) + } else if len(ref.Digest()) != 0 { + errs = append(errs, fmt.Errorf("cannot specify a non-zero --source-poll-interval-minutes for a digest based catalog image %s", o.Image)) + } + } + return errors.NewAggregate(errs) +} diff --git a/internal/pkg/v1/action/catalog_create.go b/internal/pkg/v1/action/catalog_create.go index c286ee0..bc484b7 100644 --- a/internal/pkg/v1/action/catalog_create.go +++ b/internal/pkg/v1/action/catalog_create.go @@ -75,8 +75,7 @@ func (i *CatalogCreate) buildCatalog() olmv1.ClusterCatalog { Source: olmv1.CatalogSource{ Type: olmv1.SourceTypeImage, Image: &olmv1.ImageSource{ - Ref: i.ImageSourceRef, - PollIntervalMinutes: &i.PollIntervalMinutes, + Ref: i.ImageSourceRef, }, }, Priority: i.Priority, @@ -86,6 +85,9 @@ func (i *CatalogCreate) buildCatalog() olmv1.ClusterCatalog { if !i.Available { catalog.Spec.AvailabilityMode = olmv1.AvailabilityModeUnavailable } + if i.PollIntervalMinutes > 0 { + catalog.Spec.Source.Image.PollIntervalMinutes = &i.PollIntervalMinutes + } return catalog } diff --git a/internal/pkg/v1/action/catalog_update.go b/internal/pkg/v1/action/catalog_update.go index 2d3e81f..96c5a70 100644 --- a/internal/pkg/v1/action/catalog_update.go +++ b/internal/pkg/v1/action/catalog_update.go @@ -6,6 +6,7 @@ import ( "regexp" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" olmv1 "github.com/operator-framework/operator-controller/api/v1" @@ -31,8 +32,10 @@ type CatalogUpdate struct { func NewCatalogUpdate(config *action.Configuration) *CatalogUpdate { return &CatalogUpdate{ - config: config, - Logf: func(string, ...interface{}) {}, + config: config, + Logf: func(string, ...interface{}) {}, + PollIntervalMinutes: ptr.To(0), + Priority: ptr.To(int32(0)), } } @@ -111,9 +114,7 @@ func (i *CatalogUpdate) setUpdatedCatalog(catalog *olmv1.ClusterCatalog) { catalog.Spec.Source.Image.Ref = i.ImageRef } - if i.AvailabilityMode != "" { - catalog.Spec.AvailabilityMode = olmv1.AvailabilityMode(i.AvailabilityMode) - } + catalog.Spec.AvailabilityMode = olmv1.AvailabilityMode(i.AvailabilityMode) } func (i *CatalogUpdate) setDefaults(catalog *olmv1.ClusterCatalog) { diff --git a/internal/pkg/v1/action/extension_update.go b/internal/pkg/v1/action/extension_update.go index 988714d..80e9081 100644 --- a/internal/pkg/v1/action/extension_update.go +++ b/internal/pkg/v1/action/extension_update.go @@ -7,7 +7,6 @@ import ( "slices" "time" - "github.com/blang/semver/v4" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -21,12 +20,9 @@ type ExtensionUpdate struct { config *action.Configuration ExtensionName string - Version string - Channels []string - Selector string - // parsedSelector is used internally to avoid potentially costly transformations - // between string and metav1.LabelSelector formats - parsedSelector *metav1.LabelSelector + Version string + Channels []string + CatalogSelector *metav1.LabelSelector UpgradeConstraintPolicy string Labels map[string]string IgnoreUnset bool @@ -61,18 +57,6 @@ func (i *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, err i.setDefaults(ext) - if i.Version != "" { - if _, err = semver.ParseRange(i.Version); err != nil { - return nil, fmt.Errorf("failed parsing version: %w", err) - } - } - if i.Selector != "" && i.parsedSelector == nil { - i.parsedSelector, err = metav1.ParseToLabelSelector(i.Selector) - if err != nil { - return nil, fmt.Errorf("failed parsing selector: %w", err) - } - } - constraintPolicy := olmv1.UpgradeConstraintPolicy(i.UpgradeConstraintPolicy) if !i.needsUpdate(ext, constraintPolicy) { return nil, ErrNoChange @@ -127,8 +111,8 @@ func (i *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { if len(i.Labels) == 0 { i.Labels = ext.Labels } - if i.Selector == "" && catalogSrc.Selector != nil { - i.parsedSelector = catalogSrc.Selector + if i.CatalogSelector == nil { + i.CatalogSelector = catalogSrc.Selector } } @@ -138,9 +122,9 @@ func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPoli // object string form is used for comparison to: // - remove the need for potentially costly metav1.FormatLabelSelector calls // - avoid having to handle potential reordering of items from on cluster state - sameSelectors := (catalogSrc.Selector == nil && i.parsedSelector == nil) || - (catalogSrc.Selector != nil && i.parsedSelector != nil && - catalogSrc.Selector.String() == i.parsedSelector.String()) + sameSelectors := (catalogSrc.Selector == nil && i.CatalogSelector == nil) || + (catalogSrc.Selector != nil && i.CatalogSelector != nil && + catalogSrc.Selector.String() == i.CatalogSelector.String()) if catalogSrc.Version == i.Version && slices.Equal(catalogSrc.Channels, i.Channels) && @@ -157,7 +141,7 @@ func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPoli func (i *ExtensionUpdate) prepareUpdatedExtension(ext *olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) { ext.SetLabels(i.Labels) ext.Spec.Source.Catalog.Version = i.Version - ext.Spec.Source.Catalog.Selector = i.parsedSelector + ext.Spec.Source.Catalog.Selector = i.CatalogSelector ext.Spec.Source.Catalog.Channels = i.Channels ext.Spec.Source.Catalog.UpgradeConstraintPolicy = constraintPolicy ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(i.CRDUpgradeSafetyEnforcement) diff --git a/olmv1.md b/olmv1.md index 5fb8313..6b1422e 100644 --- a/olmv1.md +++ b/olmv1.md @@ -11,7 +11,7 @@ Within the repository, these are defined in `internal/cmd/olmv1.go`, which in tu ```bash $ kubectl operator olmv1 --help -Manage extensions via `olmv1` in a cluster from the command line. +Manage OLMv1 resources like clusterextensions and clustercatalogs from the command line. Usage: operator olmv1 [command] @@ -21,6 +21,7 @@ Available Commands: delete Delete a resource get Display one or many resource(s) install Install a resource + search Search for packages update Update a resource ``` @@ -58,11 +59,13 @@ Aliases: catalog, catalogs Flags: - --available true means that the catalog should be active and serving data (default true) - --cleanup-timeout duration the amount of time to wait before cancelling cleanup after a failed creation attempt (default 1m0s) - --labels stringToString labels that will be added to the catalog (default []) - --priority int32 priority determines the likelihood of a catalog being selected in conflict scenarios - --source-poll-interval-minutes int catalog source polling interval [in minutes] (default 10) + --available string determines whether a catalog should be active and serving data. Setting the flag to false means the catalog will not serve its contents. + --cleanup-timeout duration the amount of time to wait before cancelling cleanup after a failed creation attempt. (default 1m0s) + --dry-run string display the object that would be sent on a request without applying it. One of: (All) + --labels stringToString labels to add to the catalog. Set a label's value as empty to remove it. (default []) + -o, --output string output format for dry-run manifests. One of: (json, yaml) + --priority int32 relative priority of the catalog among all on-cluster catalogs for installing or updating packages. A higher number equals greater priority; negative values indicate less priority than the default. + --source-poll-interval-minutes int the interval in minutes to poll the catalog's source image for new content. Only valid for tag based source image references. Set to 0 or -1 to disable polling. ``` The flags allow for setting most mutable fields: @@ -71,8 +74,10 @@ The flags allow for setting most mutable fields: - `--labels`: Additional labels to add to the newly created `ClusterCatalog` as `key=value` pairs. This flag may be specified multiple times. - `--priority`: Integer priority used for ordering `ClusterCatalogs` in case two extension packages have the same name across `ClusterCatalogs`, with a higher value indicating greater relative priority. Default: 0 - `--source-poll-interval-minutes`: The polling interval to check for changes if the `ClusterCatalog` source image provided is not a digest based image, i.e, if it is referenced by tag. Set to 0 to disable polling. Default: 10 +- `--dry-run`: Generate the manifest that would be applied with the command without actually applying it to the cluster. +- `--output`: The format for displaying manifests if `--dry-run` is specified. -The command requires at minimum a resource name and image reference: +The command requires at minimum a resource name and image reference. ```bash $ kubectl operator olmv1 create catalog mycatalog myorg/mycatalogrepo:tag ``` @@ -106,12 +111,18 @@ Usage: operator olmv1 install extension [flags] Flags: - -c, --channels strings channels which would be used for getting updates, e.g, --channels "stable,dev-preview,preview" - -d, --cleanup-timeout duration the amount of time to wait before cancelling cleanup after a failed creation attempt (default 1m0s) - -n, --namespace string namespace to install the operator in - -p, --package-name string package name of the operator to install - -s, --service-account string service account name to use for the extension installation (default "default") - -v, --version string version (or version range) from which to resolve bundles + -l, --catalog-selector string selector (label query) to filter catalogs to search for the package, supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 in (value3)). Matching objects must satisfy all of the specified label constraints. + -c, --channels strings channels to be used for getting updates. If omitted, extension versions in all channels will be considered for upgrades. When used with '--version', only package versions meeting both constraints will be considered. + --cleanup-timeout duration the amount of time to wait before cancelling cleanup after a failed creation attempt (default 1m0s) + --crd-upgrade-safety-enforcement string policy for preflight CRD Upgrade safety checks. One of: [Strict None], (default Strict) + --dry-run string display the object that would be sent on a request without applying it. One of: (All) + --labels stringToString labels to add to the extension. Set a label's value as empty to remove that label (default []) + -n, --namespace string namespace to install the operator in (default "olmv1-system") + -o, --output string output format for dry-run manifests. One of: (json, yaml) + -p, --package-name string package name of the operator to install. Required. + -s, --service-account string service account name to use for the extension installation (default "default") + --upgrade-constraint-policy string controls whether the package upgrade path(s) defined in the catalog are enforced. One of [CatalogProvided SelfCertified], (default CatalogProvided) + -v, --version string version (or version range) in semver format to limit the allowable package versions to. If used with '--channel', only package versions meeting both constraints will be considered. ``` The flags allow for setting most mutable fields: @@ -119,8 +130,14 @@ The flags allow for setting most mutable fields: - **`-p`, `--package-name`**: Name of the package to install. **Required** - `-c`, `--channels`: An optional list of channels within a package to restrict searches for an installable version to. - `-d`, `--cleanup-timeout`: If a `ClusterExtension` creation attempt fails due to the resource never becoming healthy, `olmv1` cleans up by deleting the failed resource, with a timeout specified by `--cleanup-timeout`. Default: 1 minute (1m) -- `-s`, `--service-account`: Name of the service account present in the namespace specified by `--namespace` to use for creating and managing resources for the new `ClusterExtension`. -- `-v`, `--version`: A version or version range to restrict search for an installable version to. +- `-s`, `--service-account`: Name of the ServiceAccount present in the namespace specified by `--namespace` to use for creating and managing resources for the new `ClusterExtension`. If not specified, the command expects a ServiceAccount `default` to be present in the namespace provided by `--namespace` with the required permissions to create and manage all the resources the `ClusterExtension` may require. +- `-v`, `--version`: A version or version range to restrict search for an installable version to. If specified along with `--channels`, only versions in the version range belonging to one or more of the channels specified will be allowed. +- `--dry-run`: Generate the manifest that would be applied with the command without actually applying it to the cluster. +- `--output`: The format for displaying manifests if `--dry-run` is specified. +- `--catalog-selector`: Limit the sources that the package specified by the ClusterExtension can be installed from to ClusterCatalogs matching the provided label selector. Only useful if the ClusterCatalogs on cluster have been labelled meaningfully, such as by maturity, provider etc. eg: +- `--labels`: Labels to be added to the new ClusterExtension. +- `--upgrade-constraint-policy`:Controls how upgrade versions are picked for the ClusterExtension. If set to `SelfCertified`, upgrade to any version of the package (even earlier versions, i.e, downgrades) are allowed. If set to `CatalogProvided`, only upgrade paths mentioned in the ClusterCatalog are allowed for the package. Note that `SelfCertified` upgrades may be unsafe and lead to data loss. +- `--crd-upgrade-safety-enforcement`: configures pre-flight CRD Upgrade safety checks. If set to `Strict`, an upgrade will be blocked if it has breaking changes to a CRD on cluster. If set to `None`, this pre-flight check is skipped, which may cause unsafe changes during installs and upgrades.

@@ -164,7 +181,9 @@ Aliases: catalog, catalogs [catalog_name] Flags: - --all delete all catalogs + -a, --all delete all catalogs + --dry-run string display the object that would be sent on a request without applying it. One of: (All) + -o, --output string output format for dry-run manifests. One of: (json, yaml) ``` The command requires exactly one of a resource name or the `--all` flag: @@ -173,6 +192,13 @@ $ kubectl operator olmv1 delete catalog mycatalog $ kubectl operator olmv1 delete catalog --all ``` +Using `--all` along with a resource name is invalid. For example, the following command is invalid: +```bash +$ kubectl operator olmv1 delete catalog mycatalog --all + +failed to delete catalog: cannot specify both --all and a catalog name +``` +
### olmv1 delete extension @@ -187,7 +213,9 @@ Aliases: extension, extensions [extension_name] Flags: - -a, --all delete all extensions + -a, --all delete all extensions + --dry-run string display the object that would be sent on a request without applying it. One of: (All) + -o, --output string output format for dry-run manifests. One of: (json, yaml) ``` The command requires exactly one of a resource name or the `--all` flag: @@ -196,6 +224,13 @@ $ kubectl operator olmv1 delete extension myex $ kubectl operator olmv1 delete extension --all ``` +Using `--all` along with a resource name is invalid. For example, the following command is invalid: +```bash +$ kubectl operator olmv1 delete extension myex --all + +failed to delete extension: cannot specify both --all and an extension name +``` +

@@ -228,32 +263,37 @@ Usage: operator olmv1 update catalog [flags] Flags: - --availability-mode string available means that the catalog should be active and serving data - --ignore-unset when enabled, any unset flag value will not be changed. Disabling this flag replaces all other unset or empty values with a default value, overwriting any values on the existing CR (default true) - --image string Image reference for the catalog source. Leave unset to retain the current image. - --labels stringToString labels that will be added to the catalog (default []) - --priority int32 priority determines the likelihood of a catalog being selected in conflict scenarios - --source-poll-interval-minutes int catalog source polling interval [in minutes]. Set to 0 or -1 to remove the polling interval. (default 5) + --available string determines whether a catalog should be active and serving data. Setting the flag to false means the catalog will not serve its contents. Set to true by default for new catalogs. + --dry-run string display the object that would be sent on a request without applying it. One of: (All) + --ignore-unset set to false to revert all values not specifically set with flags in the command to their default as defined by the clustercatalog customresoucedefinition. (default true) + --image string image reference for the catalog source. Leave unset to retain the current image. + --labels stringToString labels to add to the catalog. Set a label's value as empty to remove it. (default []) + -o, --output string output format for dry-run manifests. One of: (json, yaml) + --priority int32 relative priority of the catalog among all on-cluster catalogs for installing or updating packages. A higher number equals greater priority; negative values indicate less priority than the default. + --source-poll-interval-minutes int the interval in minutes to poll the catalog's source image for new content. Only valid for tag based source image references. Set to 0 or -1 to disable polling. + ``` The flags allow for setting most mutable fields: - `--ignore-unset`: Sets the behavior of unspecified or empty flags, whether they should be ignored, preserving the current value on the resource, or treated as valid and used to set the field values to their default value. -- `--availablity-mode`: Sets whether the `ClusterCatalog` should be actively serving and making its contents available on cluster. Valid values: `Available`|`Unavailable`. +- `--available`: Sets whether the `ClusterCatalog` should be actively serving and making its contents available on cluster. Valid values: `true`|`false`. - `--image`: Update the image reference for the `ClusterCatalog`. - `--labels`: Additional labels to add to the `ClusterCatalog` as `key=value` pairs. This flag may be specified multiple times. Setting the value of a label to an empty string deletes the label from the resource. - `--priority`: Integer priority used for ordering `ClusterCatalogs` in case two extension packages have the same name across `ClusterCatalogs`, with a higher value indicating greater relative priority. - `--source-poll-interval-minutes`: The polling interval to check for changes if the `ClusterCatalog` source image provided is not a digest based image, i.e, if it is referenced by tag. Set to 0 or -1 to disable polling. +- `--dry-run`: Generate the manifest that would be applied with the command without actually applying it to the cluster. +- `--output`: The format for displaying manifests if `--dry-run` is specified.
To update specific fields on a catalog, like adding a new label or setting availability, the required flag may be used on its own: ```bash -$ kubectl operator olmv1 update catalog mycatalog --label newlabel=newkey --label labeltoremove= -$ kubectl operator olmv1 update catalog --availability-mode Available +$ kubectl operator olmv1 update catalog mycatalog --labels newlabel=newkey --labels labeltoremove= +$ kubectl operator olmv1 update catalog --available true ``` To reset a specific field on a catalog to its default, the value needs to be provided or all existing fields must be specified with `--ignore-unset`. ```bash -$ kubectl operator olmv1 update catalog mycatalog --availability-mode Available +$ kubectl operator olmv1 update catalog mycatalog --available true $ kubectl operator olmv1 update catalog mycatalog --ignore-unset=false --priority=10 --source-poll-interval-minutes=-1 --image=myorg/mycatalogrepo:tag --labels existing1=labelvalue1 --labels existing2=labelvalue2 ``` @@ -268,31 +308,43 @@ Usage: operator olmv1 update extension [flags] Flags: - --channels stringArray desired channels for extension versions. AND operation with version. If empty or not specified, all available channels will be taken into consideration - --ignore-unset when enabled, any unset flag value will not be changed. Disabling this flag replaces all other unset or empty values with a default value, overwriting any values on the existing CR (default true) - --labels stringToString labels that will be set on the extension (default []) - --selector string filters the set of catalogs used in the bundle selection process. Empty means that all catalogs will be used in the bundle selection process - --upgrade-constraint-policy string controls whether the upgrade path(s) defined in the catalog are enforced. One of CatalogProvided|SelfCertified, Default: CatalogProvided - --version string desired extension version (single or range) in semVer format. AND operation with channels + -l, --catalog-selector string selector (label query) to filter catalogs to search for the package, supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 in (value3)). Matching objects must satisfy all of the specified label constraints. + -c, --channels strings channels to be used for getting updates. If omitted, extension versions in all channels will be considered for upgrades. When used with '--version', only package versions meeting both constraints will be considered. + --crd-upgrade-safety-enforcement string policy for preflight CRD Upgrade safety checks. One of: [Strict None], (default Strict) + --dry-run string display the object that would be sent on a request without applying it. One of: (All) + --ignore-unset set to false to revert all values not specifically set with flags in the command to their default as defined by the clusterextension customresoucedefinition. (default true) + --labels stringToString labels to add to the extension. Set a label's value as empty to remove that label (default []) + -o, --output string output format for dry-run manifests. One of: (json, yaml) + --upgrade-constraint-policy string controls whether the package upgrade path(s) defined in the catalog are enforced. One of [CatalogProvided SelfCertified], (default CatalogProvided) + -v, --version string version (or version range) in semver format to limit the allowable package versions to. If used with '--channel', only package versions meeting both constraints will be considered. ``` The flags allow for setting most mutable fields: - `--ignore-unset`: Sets the behavior of unspecified or empty flags, whether they should be ignored, preserving the current value on the resource, or treated as valid and used to set the field values to their default value. -- `-v`, `--version`: A version or version range to restrict search for a version upgrade. +- `-v`, `--version`: A version or version range to restrict search for a version upgrade. If specified along with `--channels`, only versions in the version range belonging to one or more of the channels specified will be allowed. + Valid version range format examples: + - Exact: `--version 1.2.3` + - Range: `--version ">=1.0.0 <2.0.0"` + - Wildcard: `--version 1.2.x` (any patch version of 1.2) + - Minimum: `--version ">=1.5.0"` - `-c`, `--channels`: An optional list of channels within a package to restrict searches for updates. If empty or unspecified, no channel restrictions apply while searching for valid package versions for extension updates. - `--upgrade-constraint-policy`: Specifies upgrade selection behavior. Valid values: `CatalogProvided|SelfCertified`. `SelfCertified` can be used to override upgrade graphs within a catalog and upgrade to any version at the risk of using non-standard upgrade paths. `CatalogProvided` restricts upgrades to standard paths between versions explicitly allowed within the `ClusterCatalog`. - `--labels`: Additional labels to add to the `ClusterExtension` as `key=value` pairs. This flag may be specified multiple times. Setting the value of a label to an empty string deletes the label from the resource. +- `--dry-run`: Generate the manifest that would be applied with the command without actually applying it to the cluster. +- `--output`: The format for displaying manifests if `--dry-run` is specified. +- `--catalog-selector`: Limit the sources that the package specified by the ClusterExtension can be installed from to ClusterCatalogs matching the provided label selector. +- `--crd-upgrade-safety-enforcement`: configures pre-flight CRD Upgrade safety checks. If set to `Strict`, an upgrade will be blocked if it has breaking changes to a CRD on cluster. If set to `None`, this pre-flight check is skipped, which may cause unsafe changes during installs and upgrades. To update specific fields on an extension, like adding a new label or updating desired version range, the required flag may be used on its own: ```bash -$ kubectl operator olmv1 update extension myex --label newlabel=newkey --label labeltoremove= +$ kubectl operator olmv1 update extension myex --labels newlabel=newkey --labels labeltoremove= $ kubectl operator olmv1 update extension myex --version 1.2.x ``` To reset a specific field to its default on an extension, the value needs to be provided or all existing fields must be specified with `--ignore-unset`. ```bash -$ kubectl operator olmv1 update catalog --upgrade-constraint-policy CatalogProvided -$ kubectl operator olmv1 update catalog --ignore-unset=false --version=1.0.x --channels=stable,candidate --labels existing1=labelvalue1 --labels existing2=labelvalue2 +$ kubectl operator olmv1 update extension --upgrade-constraint-policy CatalogProvided +$ kubectl operator olmv1 update extension --ignore-unset=false --version=1.0.x --channels=stable,candidate --labels existing1=labelvalue1 --labels existing2=labelvalue2 ```
@@ -326,8 +378,16 @@ Usage: Aliases: catalog, catalogs + +Flags: + -o, --output string output format. One of: (json, yaml) + -l, --selector string selector (label query) to filter on, supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 in (value3)). Matching objects must satisfy all of the specified label constraints. ``` +The flags allow for limiting or formatting output: +- `--output`: The format for displaying the resources. Valid values: json, yaml. +- `--selector`: Limit the resources listed to those matching the provided label selector. + ```bash $ kubectl operator olmv1 get catalog NAME AVAILABILITY PRIORITY LASTUNPACKED SERVING AGE @@ -346,10 +406,74 @@ Usage: Aliases: extension, extensions [extension_name] + +Flags: + -o, --output string output format. One of: (json, yaml) + -l, --selector string selector (label query) to filter on, supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 in (value3)). Matching objects must satisfy all of the specified label constraints. ``` +The flags allow for limiting or formatting output: +- `--output`: The format for displaying the resources. Valid values: json, yaml. +- `--selector`: Limit the resources listed to those matching the provided label selector. + ```bash $ kubectl operator olmv1 get extension NAME INSTALLED BUNDLE VERSION SOURCE TYPE INSTALLED PROGRESSING AGE test-operator prometheusoperator.0.47.0 0.47.0 Community Operators Index True False 44m -``` \ No newline at end of file +``` + +## olmv1 search +Search available sources for packages or versions. Currently supports searching ClusterCatalogs + +```bash +Search one or all available catalogs for packages or versions + +Usage: + operator olmv1 search [command] + +Available Commands: + catalog Search catalogs for installable operators matching parameters +``` +
+ +### olmv1 search catalog +Search one or all available catalogs for packages or versions + +```bash +kubectl-operator olmv1 search catalog --help +Search catalogs for installable operators matching parameters + +Usage: + operator olmv1 search catalog [flags] + +Aliases: + catalog, catalogs + +Flags: + --catalog string name of the catalog to search. If not provided, all available catalogs are searched. + --catalogd-namespace string namespace for the catalogd controller (default "olmv1-system") + --list-versions list all versions available for each package + -o, --output string output format. One of: (yaml|json) + --package string search for package by name. If empty, all available packages will be listed + -l, --selector string selector (label query) to filter catalogs on, supports '=', '==', and '!=' + --timeout string timeout for fetching catalog contents (default "5m") +``` + +The flags allow for limiting or formatting output: +- `--catalog`: When non-empty, limits the listed packages or bundles to only those from the catalog provided through this flag +- `--selector`: When non-empty, limits the listed packages or bundles to only the ones from ClusterCatalogs matching the label selector provided through this flag. +- `--timeout`: Time to wait before aborting the command +- `--catalogd-namespace`: By default, the catalogd-controller is installed in `olmv1-system`. If the catalogd-controller's service is present in another namespace, it can be specified through this flag. +- `--list-versions`: By default, the search command shows the package name, the source ClusterCatalog, the package maintainer and the valid channels available on the package, if any. If this flag is specified, it lists the versions available for each package instead of listing channels. +- `--package`: If non-empty, limit the listed packages and bundles to only those with the package name specified by this flag. +- `--output`: This flag allows the output to be provided in a specific format. Currently support yaml, json. If empty, provides a simplified table of packages instead. + +```bash +$ kubectl operator olmv1 search catalog + +PACKAGE CATALOG PROVIDER CHANNELS +accuknox-operator operatorhubio stable +ack-acm-controller operatorhubio alpha +ack-acmpca-controller operatorhubio alpha +... +``` From 4fefd4859bd0b2ce39ba34ec32d9b8ac92a7a889 Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Mon, 1 Dec 2025 22:05:07 -0500 Subject: [PATCH 10/11] fixing tests Signed-off-by: Ankita Thomas --- go.mod | 149 +++-- go.sum | 542 ++++++++---------- internal/cmd/internal/olmv1/catalog_create.go | 27 +- internal/cmd/internal/olmv1/catalog_delete.go | 20 +- internal/cmd/internal/olmv1/catalog_get.go | 27 +- internal/cmd/internal/olmv1/catalog_search.go | 25 +- internal/cmd/internal/olmv1/catalog_update.go | 39 +- .../cmd/internal/olmv1/extension_delete.go | 25 +- internal/cmd/internal/olmv1/extension_get.go | 24 +- .../cmd/internal/olmv1/extension_install.go | 40 +- .../cmd/internal/olmv1/extension_update.go | 35 +- internal/cmd/internal/olmv1/flags.go | 59 +- internal/cmd/internal/olmv1/printing.go | 36 +- internal/pkg/v1/action/action_suite_test.go | 15 + internal/pkg/v1/action/catalog_create.go | 11 +- internal/pkg/v1/action/catalog_create_test.go | 9 +- internal/pkg/v1/action/catalog_delete.go | 8 +- internal/pkg/v1/action/catalog_delete_test.go | 25 +- internal/pkg/v1/action/catalog_get.go | 10 +- internal/pkg/v1/action/catalog_get_test.go | 5 +- internal/pkg/v1/action/catalog_search.go | 18 +- internal/pkg/v1/action/catalog_search_test.go | 109 ---- internal/pkg/v1/action/catalog_update.go | 9 +- internal/pkg/v1/action/extension_delete.go | 3 +- .../pkg/v1/action/extension_delete_test.go | 21 +- internal/pkg/v1/action/extension_install.go | 2 +- internal/pkg/v1/action/extension_update.go | 46 +- .../pkg/v1/action/extension_update_test.go | 6 + internal/pkg/v1/action/helpers.go | 8 +- internal/pkg/v1/client/port_forward.go | 33 +- 30 files changed, 660 insertions(+), 726 deletions(-) delete mode 100644 internal/pkg/v1/action/catalog_search_test.go diff --git a/go.mod b/go.mod index 4c3f374..151e62b 100644 --- a/go.mod +++ b/go.mod @@ -1,83 +1,84 @@ module github.com/operator-framework/kubectl-operator -go 1.24.4 +go 1.23.4 require ( github.com/blang/semver/v4 v4.0.0 github.com/briandowns/spinner v1.23.2 - github.com/containerd/containerd v1.7.28 + github.com/containerd/containerd v1.7.26 github.com/containerd/platforms v0.2.1 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.38.2 + github.com/onsi/gomega v1.36.2 github.com/opencontainers/image-spec v1.1.1 - github.com/operator-framework/api v0.34.0 - github.com/operator-framework/operator-controller v1.5.1 + github.com/operator-framework/api v0.30.0 + github.com/operator-framework/operator-controller v1.2.0 github.com/operator-framework/operator-lifecycle-manager v0.23.1 - github.com/operator-framework/operator-registry v1.57.0 + github.com/operator-framework/operator-registry v1.50.0 github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.10.1 - github.com/spf13/pflag v1.0.9 - k8s.io/api v0.33.4 - k8s.io/apiextensions-apiserver v0.33.4 - k8s.io/apimachinery v0.33.4 - k8s.io/cli-runtime v0.33.3 - k8s.io/client-go v0.33.4 - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 - sigs.k8s.io/controller-runtime v0.21.0 - sigs.k8s.io/yaml v1.6.0 + github.com/spf13/cobra v1.9.1 + github.com/spf13/pflag v1.0.6 + k8s.io/api v0.32.2 + k8s.io/apiextensions-apiserver v0.32.2 + k8s.io/apimachinery v0.32.2 + k8s.io/cli-runtime v0.32.2 + k8s.io/client-go v0.32.2 + sigs.k8s.io/controller-runtime v0.20.2 + sigs.k8s.io/yaml v1.4.0 ) require ( - cel.dev/expr v0.24.0 // indirect - github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect - github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect - github.com/BurntSushi/toml v1.5.0 // indirect + cel.dev/expr v0.18.0 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.13.0 // indirect - github.com/antlr4-go/antlr/v4 v4.13.1 // indirect - github.com/containerd/cgroups/v3 v3.0.5 // indirect - github.com/containerd/containerd/api v1.9.0 // indirect - github.com/containerd/continuity v0.4.5 // indirect - github.com/containerd/errdefs v1.0.0 // indirect + github.com/Microsoft/hcsshim v0.12.9 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/containerd/cgroups/v3 v3.0.3 // indirect + github.com/containerd/containerd/api v1.8.0 // indirect + github.com/containerd/continuity v0.4.4 // indirect + github.com/containerd/errdefs v0.3.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/ttrpc v1.2.7 // indirect - github.com/containerd/typeurl/v2 v2.2.3 // indirect - github.com/containers/common v0.64.1 // indirect - github.com/containers/image/v5 v5.36.2 // indirect + github.com/containerd/typeurl/v2 v2.2.0 // indirect + github.com/containers/common v0.61.0 // indirect + github.com/containers/image/v5 v5.33.1 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect - github.com/containers/ocicrypt v1.2.1 // indirect - github.com/containers/storage v1.59.1 // indirect + github.com/containers/ocicrypt v1.2.0 // indirect + github.com/containers/storage v1.56.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/cli v28.3.3+incompatible // indirect + github.com/docker/cli v27.5.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v28.3.3+incompatible // indirect - github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/docker/docker v27.5.0+incompatible // indirect + github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/fatih/color v1.18.0 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.8.0 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.6.2 // indirect - github.com/go-git/go-git/v5 v5.16.2 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-git/go-billy/v5 v5.6.1 // indirect + github.com/go-git/go-git/v5 v5.13.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.21.1 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect - github.com/google/cel-go v0.26.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.22.1 // indirect github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/h2non/filetype v1.1.3 // indirect github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -92,52 +93,50 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.5.0 // indirect - github.com/moby/sys/capability v0.4.0 // indirect + github.com/moby/sys/capability v0.3.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect - github.com/moby/sys/sequential v0.6.0 // indirect - github.com/moby/sys/user v0.4.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.3.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect - github.com/moby/term v0.5.2 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/runtime-spec v1.2.1 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/stoewer/go-strcase v1.3.1 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/bbolt v1.4.3 // indirect + go.etcd.io/bbolt v1.3.11 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.12.0 // indirect - google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect - google.golang.org/grpc v1.75.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.opentelemetry.io/otel v1.33.0 // indirect + go.opentelemetry.io/otel/metric v1.33.0 // indirect + go.opentelemetry.io/otel/trace v1.33.0 // indirect + golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect + google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect + google.golang.org/grpc v1.68.1 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a // indirect + k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect + k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect ) diff --git a/go.sum b/go.sum index 8691120..d82af7f 100644 --- a/go.sum +++ b/go.sum @@ -1,50 +1,48 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= +cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA= -github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok= -github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= -github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= -github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= -github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= +github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= +github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w= github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= -github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= -github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c= -github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs= -github.com/containerd/containerd/api v1.9.0 h1:HZ/licowTRazus+wt9fM6r/9BQO7S0vD5lMcWspGIg0= -github.com/containerd/containerd/api v1.9.0/go.mod h1:GhghKFmTR3hNtyznBoQ0EMWr9ju5AqHjcZPsSpTKutI= -github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= -github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= -github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= -github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= +github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= +github.com/containerd/containerd v1.7.26 h1:3cs8K2RHlMQaPifLqgRyI4VBkoldNdEw62cb7qQga7k= +github.com/containerd/containerd v1.7.26/go.mod h1:m4JU0E+h0ebbo9yXD7Hyt+sWnc8tChm7MudCjj4jRvQ= +github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0= +github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= +github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII= +github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= +github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4= +github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -53,23 +51,23 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ= github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= -github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= -github.com/containers/common v0.64.1 h1:E8vSiL+B84/UCsyVSb70GoxY9cu+0bseLujm4EKF6GE= -github.com/containers/common v0.64.1/go.mod h1:CtfQNHoCAZqWeXMwdShcsxmMJSeGRgKKMqAwRKmWrHE= -github.com/containers/image/v5 v5.36.2 h1:GcxYQyAHRF/pLqR4p4RpvKllnNL8mOBn0eZnqJbfTwk= -github.com/containers/image/v5 v5.36.2/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4= +github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= +github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= +github.com/containers/common v0.61.0 h1:j/84PTqZIKKYy42OEJsZmjZ4g4Kq2ERuC3tqp2yWdh4= +github.com/containers/common v0.61.0/go.mod h1:NGRISq2vTFPSbhNqj6MLwyes4tWSlCnqbJg7R77B8xc= +github.com/containers/image/v5 v5.33.1 h1:nTWKwxAlY0aJrilvvhssqssJVnley6VqxkLiLzTEYIs= +github.com/containers/image/v5 v5.33.1/go.mod h1:/FJiLlvVbeBxWNMPVPPIWJxHTAzwBoFvyN0a51zo1CE= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= -github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM= -github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ= -github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs= -github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0= +github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM= +github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U= +github.com/containers/storage v1.56.1 h1:gDZj/S6Zxus4Xx42X6iNB3ODXuh0qoOdH/BABfrvcKo= +github.com/containers/storage v1.56.1/go.mod h1:c6WKowcAlED/DkWGNuL9bvGYqIWCVy7isRMdCSKWNjk= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= -github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -77,77 +75,75 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/distribution v2.7.1+incompatible h1:aGFx4EvJWKEh//lHPLwFhFgwFHKH06TzNVPamrMn04M= -github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= -github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU= +github.com/distribution/distribution/v3 v3.0.0-rc.1 h1:6M4ewmPBUhF7wtQ8URLOQ1W/PQuVKiD1u8ymwLDUGqQ= +github.com/distribution/distribution/v3 v3.0.0-rc.1/go.mod h1:tFjaPDeHCrLg28e4feBIy27cP+qmrc/mvkl6MFIfVi4= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo= -github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.5.0+incompatible h1:aMphQkcGtpHixwwhAXJT1rrK/detk2JIvDaFkLctbGM= +github.com/docker/cli v27.5.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= -github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= -github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/docker/docker v27.5.0+incompatible h1:um++2NcQtGRTz5eEgO6aJimo6/JxrTXC941hd05JO6U= +github.com/docker/docker v27.5.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= +github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32 h1:EHZfspsnLAz8Hzccd67D5abwLiqoqym2jz/jOS39mCk= -github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= -github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= -github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= -github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM= -github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= -github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= -github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= +github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= +github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= +github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= -github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4B/swMiAmDLs= -github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY= +github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y= +github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -161,8 +157,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= -github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= +github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40= +github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -174,11 +170,11 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU= -github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -186,21 +182,23 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= -github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0 h1:+epNPbD5EqgpEMm5wrl4Hqts3jZt8+kYaqUisuuIGTk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c h1:fEE5/5VNnYUoBOj2I9TP8Jc+a7lge3QWn9DKE7NCwfc= github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE= -github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= -github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5AmgmWNH1g+oFFVUHOEc= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= +github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= +github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= +github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -222,8 +220,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/letsencrypt/boulder v0.0.0-20250624003606-5ddd5acf990d h1:fCRb9hXR4QQJpwc7xnGugnva0DD5ollTGkys0n8aXT4= -github.com/letsencrypt/boulder v0.0.0-20250624003606-5ddd5acf990d/go.mod h1:BVoSL2Ed8oCncct0meeBqoTY7b1Mzx7WqEOZ8EisFmY= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= @@ -233,28 +229,24 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= -github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= -github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= +github.com/moby/sys/capability v0.3.0 h1:kEP+y6te0gEXIaeQhIi0s7vKs/w0RPoH1qPa6jROcVg= +github.com/moby/sys/capability v0.3.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= -github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= -github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= +github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= -github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -271,181 +263,151 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.25.2 h1:hepmgwx1D+llZleKQDMEvy8vIlCxMGt7W5ZxDjIEhsw= -github.com/onsi/ginkgo/v2 v2.25.2/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= -github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/operator-framework/api v0.34.0 h1:REiEaYhG1CWmDoajdcAdZqtgoljWG+ixMY59vUX5pFI= -github.com/operator-framework/api v0.34.0/go.mod h1:eGncUNIYvWtfGCCKmLzGXvoi3P0TDf3Yd/Z0Sn9E6SQ= -github.com/operator-framework/operator-controller v1.5.1 h1:J3xdRHzh9ajuKt/i1fWxoOLUf3kMpaOnGf1XNZ6+Klg= -github.com/operator-framework/operator-controller v1.5.1/go.mod h1:6BpO9yzrmr1s7zqnk7YUA9SJlNVD+gA25JS5sg6axCE= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/operator-framework/api v0.30.0 h1:44hCmGnEnZk/Miol5o44dhSldNH0EToQUG7vZTl29kk= +github.com/operator-framework/api v0.30.0/go.mod h1:FYxAPhjtlXSAty/fbn5YJnFagt6SpJZJgFNNbvDe5W0= +github.com/operator-framework/operator-controller v1.2.0 h1:5fn41pZuJ41jHUwWSts8igDN/IXILeLyqRKnMpN4S8I= +github.com/operator-framework/operator-controller v1.2.0/go.mod h1:lDudFGy4YtcMFcUDYLet3mUA/Wzq6pTVrLTBWOZLp/Q= github.com/operator-framework/operator-lifecycle-manager v0.23.1 h1:Xw2ml1T4W2ieoFaVwanW/eFlZ11yAOJZUpUI8RLSql8= github.com/operator-framework/operator-lifecycle-manager v0.23.1/go.mod h1:q/QgVi/WooEyOFw8ipQrb2A/InjM4djCwPf7IlCpSOQ= -github.com/operator-framework/operator-registry v1.57.0 h1:mQ4c8A8VUxZPJ0QCFRNio+7JEsLX6eKxlDSl6ORCRdk= -github.com/operator-framework/operator-registry v1.57.0/go.mod h1:9rAZH/LZ/ttEuTvL1D4KApGqOtRDE6fJzzOrJNcBu7g= -github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= -github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I= -github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= -github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= +github.com/operator-framework/operator-registry v1.50.0 h1:kMAwsKAEDjuSx5dGchMX+CD3SMHWwOAC/xyK3LQweB4= +github.com/operator-framework/operator-registry v1.50.0/go.mod h1:713Z/XzA5jViFMGIsXmfAcpA6h5uUKqUl3fO1t4taa0= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M= -github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= -github.com/prometheus/client_golang v1.23.1 h1:w6gXMLQGgd0jXXlote9lRHMe0nG01EbnJT+C0EJru2Y= -github.com/prometheus/client_golang v1.23.1/go.mod h1:br8j//v2eg2K5Vvna5klK8Ku5pcU5r4ll73v6ik5dIQ= +github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= +github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.0 h1:K/rJPHrG3+AoQs50r2+0t7zMnMzek2Vbv31OFVsMeVY= -github.com/prometheus/common v0.66.0/go.mod h1:Ux6NtV1B4LatamKE63tJBntoxD++xmtI/lK0VtEplN4= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0 h1:uTiEyEyfLhkw678n6EulHVto8AkcXVr8zUcBJNZ0ark= -github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0/go.mod h1:eFYL/99JvdLP4T9/3FZ5t2pClnv7mMskc+WstTcyVr4= -github.com/redis/go-redis/extra/redisotel/v9 v9.10.0 h1:4z7/hCJ9Jft8EBb2tDmK38p2WjyIEJ1ShhhwAhjOCps= -github.com/redis/go-redis/extra/redisotel/v9 v9.10.0/go.mod h1:B0thqLh4hB8MvvcUKSwyP5YiIcCCp8UrQ0cA9gEqyjk= -github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs= -github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= +github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U= +github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= +github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ= +github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= +github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc= -github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw= -github.com/sigstore/fulcio v1.7.1 h1:RcoW20Nz49IGeZyu3y9QYhyyV3ZKQ85T+FXPKkvE+aQ= -github.com/sigstore/fulcio v1.7.1/go.mod h1:7lYY+hsd8Dt+IvKQRC+KEhWpCZ/GlmNvwIa5JhypMS8= -github.com/sigstore/protobuf-specs v0.4.3 h1:kRgJ+ciznipH9xhrkAbAEHuuxD3GhYnGC873gZpjJT4= -github.com/sigstore/protobuf-specs v0.4.3/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= -github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU= -github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smallstep/pkcs7 v0.2.1 h1:6Kfzr/QizdIuB6LSv8y1LJdZ3aPSfTNhTLqAx9CTLfA= -github.com/smallstep/pkcs7 v0.2.1/go.mod h1:RcXHsMfL+BzH8tRhmrF1NkkpebKpq3JEM66cOFxanf0= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= -github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= -github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= -github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs= -github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= -github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= -github.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg= -github.com/ulikunitz/xz v0.5.14/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= -github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= -github.com/vbauerster/mpb/v8 v8.10.2 h1:2uBykSHAYHekE11YvJhKxYmLATKHAGorZwFlyNw4hHM= -github.com/vbauerster/mpb/v8 v8.10.2/go.mod h1:+Ja4P92E3/CorSZgfDtK46D7AVbDqmBQRTmyTqPElo0= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= +github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= -go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib v1.3.0 h1:p9Gd+3dD7yB+AIph2Ltg11QDX6Y+yWMH0YQVTpTTP2c= -go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 h1:RyrtJzu5MAmIcbRrwg75b+w3RlZCP0vJByDVzcpAe3M= -go.opentelemetry.io/contrib/bridges/prometheus v0.61.0/go.mod h1:tirr4p9NXbzjlbruiRGp53IzlYrDk5CO2fdHj0sSSaY= -go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= -go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/contrib/bridges/prometheus v0.54.0 h1:WWL67oxtknNVMb70lJXxXruf8UyK/a9hmIE1XO3Uedg= +go.opentelemetry.io/contrib/bridges/prometheus v0.54.0/go.mod h1:LqNcnXmyULp8ertk4hUTVtSUvKXj4h1Mx7gUCSSr/q0= +go.opentelemetry.io/contrib/exporters/autoexport v0.54.0 h1:dTmcmVm4J54IRPGm5oVjLci1uYat4UDea84E2tyBaAk= +go.opentelemetry.io/contrib/exporters/autoexport v0.54.0/go.mod h1:zPp5Fwpq2Hc7xMtVttg6GhZMcfTESjVbY9ONw2o/Dc4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 h1:zwdo1gS2eH26Rg+CoqVQpEK1h8gvt5qyU5Kk5Bixvow= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0/go.mod h1:rUKCPscaRWWcqGT6HnEmYrK+YNe5+Sw64xgQTOJ5b30= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= -go.opentelemetry.io/otel/exporters/prometheus v0.58.0 h1:CJAxWKFIqdBennqxJyOgnt5LqkeFRT+Mz3Yjz3hL+h8= -go.opentelemetry.io/otel/exporters/prometheus v0.58.0/go.mod h1:7qo/4CLI+zYSNbv0GMNquzuss2FVZo3OYrGh96n4HNc= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2/go.mod h1:ZccPZoPOoq8x3Trik/fCsba7DEYDUnN6yX79pgp2BUQ= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 h1:G8Xec/SgZQricwWBJF/mHZc7A02YHedfFDENwJEdRA0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= -go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= -go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= -go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= -go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 h1:4d++HQ+Ihdl+53zSjtsCUFDmNMju2FC9qFkUlTxPLqo= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0/go.mod h1:mQX5dTO3Mh5ZF7bPKDkt5c/7C41u/SiDr9XgTpzXXn8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0/go.mod h1:t4BrYLHU450Zo9fnydWlIuswB1bm7rM8havDpWOJeDo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 h1:xvhQxJ/C9+RTnAj5DpTg7LSM1vbbMTiXt7e9hsfqHNw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0/go.mod h1:Fcvs2Bz1jkDM+Wf5/ozBGmi3tQ/c9zPKLnsipnfhGAo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= +go.opentelemetry.io/otel/exporters/prometheus v0.51.0 h1:G7uexXb/K3T+T9fNLCCKncweEtNEBMTO+46hKX5EdKw= +go.opentelemetry.io/otel/exporters/prometheus v0.51.0/go.mod h1:v0mFe5Kk7woIh938mrZBJBmENYquyA0IICrlYm4Y0t4= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0 h1:ThVXnEsdwNcxdBO+r96ci1xbF+PgNjwlk457VNuJODo= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.5.0/go.mod h1:rHWcSmC4q2h3gje/yOq6sAOaq8+UHxN/Ru3BbmDXOfY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 h1:X3ZjNp36/WlkSYx0ul2jw4PtbNEDDeLskw3VPsrpYM0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0/go.mod h1:2uL/xnOXh0CHOBFCWXz5u1A4GXLiW+0IQIzVbeOEQ0U= +go.opentelemetry.io/otel/log v0.5.0 h1:x1Pr6Y3gnXgl1iFBwtGy1W/mnzENoK0w0ZoaeOI3i30= +go.opentelemetry.io/otel/log v0.5.0/go.mod h1:NU/ozXeGuOR5/mjCRXYbTC00NFJ3NYuraV/7O78F0rE= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/sdk/log v0.5.0 h1:A+9lSjlZGxkQOr7QSBJcuyyYBw79CufQ69saiJLey7o= +go.opentelemetry.io/otel/sdk/log v0.5.0/go.mod h1:zjxIW7sw1IHolZL2KlSAtrUi8JHttoeiQy43Yl3WuVQ= +go.opentelemetry.io/otel/sdk/metric v1.29.0 h1:K2CfmJohnRgvZ9UAj2/FhIf/okdWcNdBwe1m8xFXiSY= +go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= -golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 h1:aWwlzYV971S4BXRS9AmqwDLAD85ouC6X+pocatKY58c= +golang.org/x/exp v0.0.0-20250228200357-dead58393ab7/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -457,18 +419,18 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -483,16 +445,16 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -502,32 +464,30 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU= -google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU= +google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -537,8 +497,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -559,44 +519,38 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= -gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.33.4 h1:oTzrFVNPXBjMu0IlpA2eDDIU49jsuEorGHB4cvKupkk= -k8s.io/api v0.33.4/go.mod h1:VHQZ4cuxQ9sCUMESJV5+Fe8bGnqAARZ08tSTdHWfeAc= -k8s.io/apiextensions-apiserver v0.33.4 h1:rtq5SeXiDbXmSwxsF0MLe2Mtv3SwprA6wp+5qh/CrOU= -k8s.io/apiextensions-apiserver v0.33.4/go.mod h1:mWXcZQkQV1GQyxeIjYApuqsn/081hhXPZwZ2URuJeSs= -k8s.io/apimachinery v0.33.4 h1:SOf/JW33TP0eppJMkIgQ+L6atlDiP/090oaX0y9pd9s= -k8s.io/apimachinery v0.33.4/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/apiserver v0.33.4 h1:6N0TEVA6kASUS3owYDIFJjUH6lgN8ogQmzZvaFFj1/Y= -k8s.io/apiserver v0.33.4/go.mod h1:8ODgXMnOoSPLMUg1aAzMFx+7wTJM+URil+INjbTZCok= -k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA= -k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo= -k8s.io/client-go v0.33.4 h1:TNH+CSu8EmXfitntjUPwaKVPN0AYMbc9F1bBS8/ABpw= -k8s.io/client-go v0.33.4/go.mod h1:LsA0+hBG2DPwovjd931L/AoaezMPX9CmBgyVyBZmbCY= -k8s.io/component-base v0.33.4 h1:Jvb/aw/tl3pfgnJ0E0qPuYLT0NwdYs1VXXYQmSuxJGY= -k8s.io/component-base v0.33.4/go.mod h1:567TeSdixWW2Xb1yYUQ7qk5Docp2kNznKL87eygY8Rc= +k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= +k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= +k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= +k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw= +k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM= +k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks= +k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8= +k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= +k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= +k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= +k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a h1:ZV3Zr+/7s7aVbjNGICQt+ppKWsF1tehxggNfbM7XnG8= -k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -oras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg= -oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= -oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= -sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc= +sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI= -sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= -sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/internal/cmd/internal/olmv1/catalog_create.go b/internal/cmd/internal/olmv1/catalog_create.go index 4a56dd1..e27374c 100644 --- a/internal/cmd/internal/olmv1/catalog_create.go +++ b/internal/cmd/internal/olmv1/catalog_create.go @@ -5,22 +5,23 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/errors" ) type catalogCreateOptions struct { - mutableCatalogOptions dryRunOptions + mutableCatalogOptions } -// NewCatalogCreateCmd allows creating a new catalog +// NewCatalogCreateCmd creates a new catalog, requiring a minimum +// of a name for the new catalog and a source image reference func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogCreate(cfg) i.Logf = log.Printf @@ -36,20 +37,24 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { i.ImageSourceRef = args[1] opts.Image = i.ImageSourceRef if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %s", err.Error()) + log.Fatalf("failed to parse flags: %w", err) } i.DryRun = opts.DryRun i.Output = opts.Output + i.AvailabilityMode = opts.AvailabilityMode + i.Priority = opts.Priority + i.Labels = opts.Labels + i.PollIntervalMinutes = opts.PollIntervalMinutes catalogObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to create catalog %q: %v\n", i.CatalogName, err) + log.Fatalf("failed to create catalog %q: %w", i.CatalogName, err) } if len(i.DryRun) == 0 { - log.Printf("catalog %q created\n", i.CatalogName) + log.Printf("catalog %q created", i.CatalogName) return } if len(i.Output) == 0 { - log.Printf("catalog %q created (dry run)\n", i.CatalogName) + log.Printf("catalog %q created (dry run)", i.CatalogName) return } @@ -58,8 +63,8 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { printFormattedCatalogs(i.Output, *catalogObj) }, } - bindCatalogCreateFlags(cmd.Flags(), i) bindMutableCatalogFlags(cmd.Flags(), &opts.mutableCatalogOptions) + bindCatalogCreateFlags(cmd.Flags(), i) bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd diff --git a/internal/cmd/internal/olmv1/catalog_delete.go b/internal/cmd/internal/olmv1/catalog_delete.go index d3911fe..93bd05d 100644 --- a/internal/cmd/internal/olmv1/catalog_delete.go +++ b/internal/cmd/internal/olmv1/catalog_delete.go @@ -3,21 +3,21 @@ package olmv1 import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime/schema" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) type catalogDeleteOptions struct { dryRunOptions } -// NewCatalogDeleteCmd allows deleting either a single or all -// existing catalogs +// NewCatalogDeleteCmd deletes either a specific catalog by name +// or all catalogs on cluster. func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogDelete(cfg) i.Logf = log.Printf @@ -36,7 +36,7 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { i.CatalogName = args[0] } if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %s", err.Error()) + log.Fatalf("failed to parse flags: %w", err) } i.DryRun = opts.DryRun i.Output = opts.Output @@ -45,14 +45,14 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { log.Fatalf("failed to delete catalog(s): %v", err) } if len(i.DryRun) == 0 { - for _, catn := range catalogs { - log.Printf("catalog %s deleted", catn.Name) + for _, c := range catalogs { + log.Printf("catalog %q deleted", c.Name) } return } if len(i.Output) == 0 { - for _, catn := range catalogs { - log.Printf("catalog %s deleted (dry run)\n", catn.Name) + for _, c := range catalogs { + log.Printf("catalog %q deleted (dry run)", c.Name) } return } diff --git a/internal/cmd/internal/olmv1/catalog_get.go b/internal/cmd/internal/olmv1/catalog_get.go index 9a2ef6f..079efda 100644 --- a/internal/cmd/internal/olmv1/catalog_get.go +++ b/internal/cmd/internal/olmv1/catalog_get.go @@ -2,53 +2,50 @@ package olmv1 import ( "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/runtime/schema" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) // NewCatalogInstalledGetCmd handles get commands in the form of: -// catalog(s) [catalog_name] - this will either list all the installed operators +// catalog(s) [catalog_name] - this will either list all the installed catalogs // if no catalog_name has been provided or display the details of the specific // one otherwise func NewCatalogInstalledGetCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogInstalledGet(cfg) i.Logf = log.Printf - catalogGetOptions := getOptions{} + var opts getOptions cmd := &cobra.Command{ Use: "catalog [catalog_name]", - Aliases: []string{"catalogs"}, + Aliases: []string{"catalogs [catalog_name]"}, Args: cobra.RangeArgs(0, 1), Short: "Display one or many installed catalogs", Run: func(cmd *cobra.Command, args []string) { if len(args) == 1 { i.CatalogName = args[0] } - var err error - switch catalogGetOptions.Output { - case "yaml", "json", "": - default: - log.Fatalf("unrecognized output format %s", catalogGetOptions.Output) + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %w", err) } - i.Selector = catalogGetOptions.Selector + i.Selector = opts.ParsedSelector installedCatalogs, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed getting installed catalog(s): %v", err) + log.Fatalf("failed getting installed catalog(s): %w", err) } for i := range installedCatalogs { installedCatalogs[i].GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) } - printFormattedCatalogs(catalogGetOptions.Output, installedCatalogs...) + printFormattedCatalogs(opts.Output, installedCatalogs...) }, } - bindGetFlags(cmd.Flags(), &catalogGetOptions) + bindGetFlags(cmd.Flags(), &opts) return cmd } diff --git a/internal/cmd/internal/olmv1/catalog_search.go b/internal/cmd/internal/olmv1/catalog_search.go index 16d0491..9a8c95c 100644 --- a/internal/cmd/internal/olmv1/catalog_search.go +++ b/internal/cmd/internal/olmv1/catalog_search.go @@ -21,40 +21,43 @@ import ( func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogSearch(cfg) i.Logf = log.Printf + var opts getOptions cmd := &cobra.Command{ Use: "catalog", Aliases: []string{"catalogs"}, - Args: cobra.RangeArgs(0, 1), Short: "Search catalogs for installable packages matching parameters", Run: func(cmd *cobra.Command, args []string) { + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %w", err) + } + i.Selector = opts.ParsedSelector catalogContents, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed querying catalog(s): %v", err) + log.Fatalf("failed querying catalog(s): %w", err) } - switch i.OutputFormat { - case "", "table": + switch opts.Output { + case "": printFormattedDeclCfg(os.Stdout, catalogContents, i.ListVersions) case "json": printDeclCfgJSON(os.Stdout, catalogContents) case "yaml": printDeclCfgYAML(os.Stdout, catalogContents) default: - log.Fatalf("unsupported output format %s: allowed formats are (json|yaml|table)", i.OutputFormat) + log.Fatalf("unsupported output format %q: allowed formats are (json|yaml)", opts.Output) } }, } bindCatalogSearchFlags(cmd.Flags(), i) + bindGetFlags(cmd.Flags(), &opts) return cmd } func bindCatalogSearchFlags(fs *pflag.FlagSet, i *v1action.CatalogSearch) { fs.StringVar(&i.CatalogName, "catalog", "", "name of the catalog to search. If not provided, all available catalogs are searched.") - fs.StringVarP(&i.Selector, "selector", "l", "", "selector (label query) to filter catalogs on, supports '=', '==', and '!='") - fs.StringVarP(&i.OutputFormat, "output", "o", "", "output format. One of: (yaml|json)") - fs.BoolVar(&i.ListVersions, "list-versions", false, "list all versions available for each package") - fs.StringVar(&i.Package, "package", "", "search for package by name. If empty, all available packages will be listed") - fs.StringVar(&i.CatalogdNamespace, "catalogd-namespace", "olmv1-system", "namespace for the catalogd controller") - fs.StringVar(&i.Timeout, "timeout", "5m", "timeout for fetching catalog contents") + fs.BoolVar(&i.ListVersions, "list-versions", false, "list all versions available for each package.") + fs.StringVar(&i.Package, "package", "", "search for package by name. If empty, all available packages will be listed.") + fs.StringVar(&i.CatalogdNamespace, "catalogd-namespace", "olmv1-system", "namespace for the catalogd controller.") + fs.StringVar(&i.Timeout, "timeout", "5m", "timeout for fetching catalog contents.") } diff --git a/internal/cmd/internal/olmv1/catalog_update.go b/internal/cmd/internal/olmv1/catalog_update.go index e4838e8..77cf70e 100644 --- a/internal/cmd/internal/olmv1/catalog_update.go +++ b/internal/cmd/internal/olmv1/catalog_update.go @@ -2,36 +2,38 @@ package olmv1 import ( "github.com/spf13/cobra" - "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/errors" ) type catalogUpdateOptions struct { - mutableCatalogOptions dryRunOptions + mutableCatalogOptions + updateDefaultFieldOptions } -// NewCatalogUpdateCmd allows updating a selected clustercatalog +// NewCatalogUpdateCmd updates one or more mutable fields +// of a catalog specified by name func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogUpdate(cfg) i.Logf = log.Printf var opts catalogUpdateOptions cmd := &cobra.Command{ - Use: "catalog ", - Short: "Update a catalog", - Args: cobra.ExactArgs(1), + Use: "catalog ", + Aliases: []string{"catalogs "}, + Short: "Update a catalog", + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.CatalogName = args[0] if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %s", err.Error()) + log.Fatalf("failed to parse flags: %w", err) } if cmd.Flags().Changed("priority") { i.Priority = &opts.Priority @@ -42,20 +44,22 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { if cmd.Flags().Changed("labels") { i.Labels = opts.Labels } + i.ImageRef = opts.Image i.AvailabilityMode = opts.AvailabilityMode + i.IgnoreUnset = opts.IgnoreUnset i.DryRun = opts.DryRun i.Output = opts.Output catalogObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to update catalog: %v", err) + log.Fatalf("failed to update catalog: %w", err) } if len(i.DryRun) == 0 { - log.Printf("catalog %q updated\n", i.CatalogName) + log.Printf("catalog %q updated", i.CatalogName) return } if len(i.Output) == 0 { - log.Printf("catalog %q updated (dry run)\n", i.CatalogName) + log.Printf("catalog %q updated (dry run)", i.CatalogName) return } @@ -64,18 +68,13 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { printFormattedCatalogs(i.Output, *catalogObj) }, } - bindCatalogUpdateFlags(cmd.Flags(), i) bindMutableCatalogFlags(cmd.Flags(), &opts.mutableCatalogOptions) + bindUpdateFieldOptions(cmd.Flags(), &opts.updateDefaultFieldOptions, "clustercatalog") bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } -func bindCatalogUpdateFlags(fs *pflag.FlagSet, i *v1action.CatalogUpdate) { - fs.StringVar(&i.ImageRef, "image", "", "image reference for the catalog source. Leave unset to retain the current image.") - fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "set to false to revert all values not specifically set with flags in the command to their default as defined by the clustercatalog customresoucedefinition.") -} - func (o *catalogUpdateOptions) validate() error { var errs []error if err := o.dryRunOptions.validate(); err != nil { diff --git a/internal/cmd/internal/olmv1/extension_delete.go b/internal/cmd/internal/olmv1/extension_delete.go index 4a76fb2..c39963a 100644 --- a/internal/cmd/internal/olmv1/extension_delete.go +++ b/internal/cmd/internal/olmv1/extension_delete.go @@ -3,19 +3,21 @@ package olmv1 import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime/schema" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) type extensionDeleteOptions struct { dryRunOptions } +// NewExtensionDeleteCmd deletes either a specific extension by name +// or all extensions on cluster. func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionDelete(cfg) i.Logf = log.Printf @@ -24,7 +26,7 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { cmd := &cobra.Command{ Use: "extension [extension_name]", Aliases: []string{"extensions [extension_name]"}, - Short: "Delete an extension", + Short: "Delete either a single or all of the existing extensions", Long: `Warning: Permanently deletes the named cluster extension object. If the extension contains CRDs, the CRDs will be deleted, which cascades to the deletion of all operands.`, @@ -37,23 +39,23 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { i.ExtensionName = args[0] } if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %s", err.Error()) + log.Fatalf("failed to parse flags: %w", err) } i.DryRun = opts.DryRun i.Output = opts.Output extensions, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to delete extension: %v", err) + log.Fatalf("failed to delete extension: %w", err) } if len(i.DryRun) == 0 { - for _, extn := range extensions { - log.Printf("extension %s deleted", extn.Name) + for _, e := range extensions { + log.Printf("extension %q deleted", e.Name) } return } if len(i.Output) == 0 { - for _, extn := range extensions { - log.Printf("extension %s deleted (dry run)\n", extn.Name) + for _, e := range extensions { + log.Printf("extension %q deleted (dry run)", e.Name) } return } @@ -67,9 +69,10 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { } bindExtensionDeleteFlags(cmd.Flags(), i) bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) + return cmd } func bindExtensionDeleteFlags(fs *pflag.FlagSet, e *v1action.ExtensionDeletion) { - fs.BoolVarP(&e.DeleteAll, "all", "a", false, "delete all extensions") + fs.BoolVarP(&e.DeleteAll, "all", "a", false, "delete all extensions.") } diff --git a/internal/cmd/internal/olmv1/extension_get.go b/internal/cmd/internal/olmv1/extension_get.go index a4cf60c..853b683 100644 --- a/internal/cmd/internal/olmv1/extension_get.go +++ b/internal/cmd/internal/olmv1/extension_get.go @@ -2,14 +2,13 @@ package olmv1 import ( "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/runtime/schema" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - "k8s.io/apimachinery/pkg/labels" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) // NewExtensionInstalledGetCmd handles get commands in the form of: @@ -19,7 +18,7 @@ import ( func NewExtensionInstalledGetCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionInstalledGet(cfg) i.Logf = log.Printf - extensionGetOptions := getOptions{} + var opts getOptions cmd := &cobra.Command{ Use: "extension [extension_name]", @@ -30,26 +29,23 @@ func NewExtensionInstalledGetCmd(cfg *action.Configuration) *cobra.Command { if len(args) == 1 { i.ExtensionName = args[0] } - var err error - if len(extensionGetOptions.Selector) > 0 { - i.Selector, err = labels.Parse(extensionGetOptions.Selector) - if err != nil { - log.Fatalf("unable to parse selector %s: %v", extensionGetOptions.Selector, err) - } + if err := opts.validate(); err != nil { + log.Fatalf("failed to parse flags: %w", err) } + i.Selector = opts.ParsedSelector installedExtensions, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed getting installed extension(s): %v", err) + log.Fatalf("failed getting installed extension(s): %w", err) } for i := range installedExtensions { installedExtensions[i].GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) } - printFormattedExtensions(extensionGetOptions.Output, installedExtensions...) + printFormattedExtensions(opts.Output, installedExtensions...) }, } - bindGetFlags(cmd.Flags(), &extensionGetOptions) + bindGetFlags(cmd.Flags(), &opts) return cmd } diff --git a/internal/cmd/internal/olmv1/extension_install.go b/internal/cmd/internal/olmv1/extension_install.go index 3cf8df2..800c3b9 100644 --- a/internal/cmd/internal/olmv1/extension_install.go +++ b/internal/cmd/internal/olmv1/extension_install.go @@ -5,14 +5,14 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/errors" ) type extensionInstallOptions struct { @@ -20,19 +20,22 @@ type extensionInstallOptions struct { mutableExtensionOptions } +// NewExtensionInstallCmd installs a new extension for a package, requiring a minimum +// of a name for the new extension and the name of the package to install func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionInstall(cfg) i.Logf = log.Printf var opts extensionInstallOptions cmd := &cobra.Command{ - Use: "extension ", - Short: "Install an extension", - Args: cobra.ExactArgs(1), + Use: "extension ", + Aliases: []string{"extensions "}, + Short: "Install an extension", + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %s", err.Error()) + log.Fatalf("failed to parse flags: %w", err) } i.Version = opts.Version i.Channels = opts.Channels @@ -44,35 +47,38 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { i.Output = opts.Output extObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to install extension %q: %s\n", i.ExtensionName, err.Error()) + log.Fatalf("failed to install extension %q: %w", i.ExtensionName, err) } if len(i.DryRun) == 0 { - log.Printf("extension %q created\n", i.ExtensionName) + log.Printf("extension %q created", i.ExtensionName) return } if len(i.Output) == 0 { - log.Printf("extension %q created (dry run)\n", i.ExtensionName) + log.Printf("extension %q created (dry run)", i.ExtensionName) return } extObj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) printFormattedExtensions(i.Output, *extObj) - }, } + bindMutableExtensionFlags(cmd.Flags(), &opts.mutableExtensionOptions) bindExtensionInstallFlags(cmd.Flags(), i) bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) - bindMutableExtensionFlags(cmd.Flags(), &opts.mutableExtensionOptions) return cmd } func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall) { - fs.StringVarP(&i.Namespace.Name, "namespace", "n", "olmv1-system", "namespace to install the operator in") //infer? - fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the operator to install. Required.") - fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation") - fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt") + fs.StringVarP(&i.Namespace.Name, "namespace", "n", "olmv1-system", "namespace to install the extension in.") //infer? + fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the extension to install. Required.") + fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation.") + fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt.") + + if err := cobra.MarkFlagRequired(fs, "package-name"); err != nil { + log.Fatalf("failed to process command flags: %w", err) + } } func (o *extensionInstallOptions) validate() error { diff --git a/internal/cmd/internal/olmv1/extension_update.go b/internal/cmd/internal/olmv1/extension_update.go index b63efc6..88e0dc3 100644 --- a/internal/cmd/internal/olmv1/extension_update.go +++ b/internal/cmd/internal/olmv1/extension_update.go @@ -2,36 +2,38 @@ package olmv1 import ( "github.com/spf13/cobra" - "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/errors" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/internal/cmd/internal/log" v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" "github.com/operator-framework/kubectl-operator/pkg/action" - - olmv1 "github.com/operator-framework/operator-controller/api/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/errors" ) type extensionUpdateOptions struct { dryRunOptions mutableExtensionOptions + updateDefaultFieldOptions } -// NewExtensionUpdateCmd allows updating a selected operator +// NewExtensionUpdateCmd updates one or more mutable fields +// of an extension specified by name func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewExtensionUpdate(cfg) i.Logf = log.Printf var opts extensionUpdateOptions cmd := &cobra.Command{ - Use: "extension ", - Short: "Update an extension", - Args: cobra.ExactArgs(1), + Use: "extension ", + Aliases: []string{"extensions "}, + Short: "Update an extension", + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %s", err.Error()) + log.Fatalf("failed to parse flags: %w", err) } i.Version = opts.Version i.Channels = opts.Channels @@ -39,18 +41,19 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { i.UpgradeConstraintPolicy = opts.UpgradeConstraintPolicy i.CRDUpgradeSafetyEnforcement = opts.CRDUpgradeSafetyEnforcement i.CatalogSelector = opts.ParsedSelector + i.IgnoreUnset = opts.IgnoreUnset i.DryRun = opts.DryRun i.Output = opts.Output extObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to update extension: %v", err) + log.Fatalf("failed to update extension: %w", err) } if len(i.DryRun) == 0 { - log.Printf("extension %q updated\n", i.ExtensionName) + log.Printf("extension %q updated", i.ExtensionName) return } if len(i.Output) == 0 { - log.Printf("extension %q updated (dry run)\n", i.ExtensionName) + log.Printf("extension %q updated (dry run)", i.ExtensionName) return } @@ -59,17 +62,13 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { printFormattedExtensions(i.Output, *extObj) }, } - bindExtensionUpdateFlags(cmd.Flags(), i) bindMutableExtensionFlags(cmd.Flags(), &opts.mutableExtensionOptions) + bindUpdateFieldOptions(cmd.Flags(), &opts.updateDefaultFieldOptions, "clusterextension") bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions) return cmd } -func bindExtensionUpdateFlags(fs *pflag.FlagSet, i *v1action.ExtensionUpdate) { - fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "set to false to revert all values not specifically set with flags in the command to their default as defined by the clusterextension customresoucedefinition.") -} - func (o *extensionUpdateOptions) validate() error { var errs []error if err := o.dryRunOptions.validate(); err != nil { diff --git a/internal/cmd/internal/olmv1/flags.go b/internal/cmd/internal/olmv1/flags.go index 0478bcf..fc88cbd 100644 --- a/internal/cmd/internal/olmv1/flags.go +++ b/internal/cmd/internal/olmv1/flags.go @@ -7,6 +7,7 @@ import ( "github.com/containerd/containerd/reference" "github.com/spf13/pflag" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/errors" olmv1 "github.com/operator-framework/operator-controller/api/v1" @@ -14,9 +15,11 @@ import ( v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" ) +// getOptions is used in searching catalogs and listing resources type getOptions struct { - Output string - Selector string + Output string + Selector string + ParsedSelector labels.Selector } func bindGetFlags(fs *pflag.FlagSet, o *getOptions) { @@ -24,7 +27,24 @@ func bindGetFlags(fs *pflag.FlagSet, o *getOptions) { fs.StringVarP(&o.Selector, "selector", "l", "", "selector (label query) to filter on, "+ "supports '=', '==', '!=', 'in', 'notin'.(e.g. -l key1=value1,key2=value2,key3 "+ "in (value3)). Matching objects must satisfy all of the specified label constraints.") +} + +func (o *getOptions) validate() error { + var errs []error + switch o.Output { + case "json", "yaml", "": + default: + errs = append(errs, fmt.Errorf("unrecognized output format %q: must be one of (json, yaml)", o.Output)) + } + if len(o.Selector) > 0 { + var err error + o.ParsedSelector, err = labels.Parse(o.Selector) + if err != nil { + errs = append(errs, fmt.Errorf("invalid `--selector` value %q: %w", o.Selector, err)) + } + } + return errors.NewAggregate(errs) } type dryRunOptions struct { @@ -33,23 +53,31 @@ type dryRunOptions struct { } func bindDryRunFlags(fs *pflag.FlagSet, o *dryRunOptions) { - fs.StringVar(&o.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)") + fs.StringVar(&o.DryRun, "dry-run", "", fmt.Sprintf("display the object that would be sent on a request without applying it. One of: (%s)", v1action.DryRunAll)) fs.StringVarP(&o.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)") } func (o *dryRunOptions) validate() error { var errs []error if len(o.DryRun) > 0 && o.DryRun != v1action.DryRunAll { - errs = append(errs, fmt.Errorf("invalid value for `--dry-run` %s, must be one of (%s)", o.DryRun, v1action.DryRunAll)) + errs = append(errs, fmt.Errorf("invalid value for `--dry-run` %q, must be one of (%s)", o.DryRun, v1action.DryRunAll)) } switch o.Output { case "json", "yaml", "": default: - errs = append(errs, fmt.Errorf("unrecognized output format %s: must be one of (json, yaml)", o.Output)) + errs = append(errs, fmt.Errorf("unrecognized output format %q: must be one of (json, yaml)", o.Output)) } return errors.NewAggregate(errs) } +type updateDefaultFieldOptions struct { + IgnoreUnset bool +} + +func bindUpdateFieldOptions(fs *pflag.FlagSet, o *updateDefaultFieldOptions, resourceType string) { + fs.BoolVar(&o.IgnoreUnset, "ignore-unset", true, fmt.Sprintf("set to false to revert all values not specifically set with flags in the command to their default as defined by the %s customresourcedefinition.", resourceType)) +} + type mutableExtensionOptions struct { Channels []string Version string @@ -65,7 +93,7 @@ func bindMutableExtensionFlags(fs *pflag.FlagSet, o *mutableExtensionOptions) { "considered for upgrades. When used with '--version', only package versions meeting both constraints will be considered.") fs.StringVarP(&o.Version, "version", "v", "", "version (or version range) in semver format to limit the allowable package versions to. If used with '--channel', "+ "only package versions meeting both constraints will be considered.") - fs.StringToStringVar(&o.Labels, "labels", map[string]string{}, "labels to add to the extension. Set a label's value as empty to remove that label") + fs.StringToStringVar(&o.Labels, "labels", map[string]string{}, "labels to add to the extension. Set a label's value as empty to remove that label.") fs.StringVar(&o.CRDUpgradeSafetyEnforcement, "crd-upgrade-safety-enforcement", "", fmt.Sprintf("policy for preflight CRD Upgrade safety checks. One of: %v, (default %s)", []string{string(olmv1.CRDUpgradeSafetyEnforcementStrict), string(olmv1.CRDUpgradeSafetyEnforcementNone)}, olmv1.CRDUpgradeSafetyEnforcementStrict)) fs.StringVar(&o.UpgradeConstraintPolicy, "upgrade-constraint-policy", "", "controls whether the package upgrade path(s) defined in the catalog are enforced."+ @@ -76,30 +104,30 @@ func bindMutableExtensionFlags(fs *pflag.FlagSet, o *mutableExtensionOptions) { "in (value3)). Matching objects must satisfy all of the specified label constraints.") } -func (o mutableExtensionOptions) validate() error { +func (o *mutableExtensionOptions) validate() error { var errs []error if len(o.Version) > 0 { if _, err := semver.ParseRange(o.Version); err != nil { - errs = append(errs, fmt.Errorf("invalid `--version` %s: %v", o.Version, err)) + errs = append(errs, fmt.Errorf("invalid `--version` %q: %w", o.Version, err)) } } switch o.CRDUpgradeSafetyEnforcement { case string(olmv1.CRDUpgradeSafetyEnforcementStrict), string(olmv1.CRDUpgradeSafetyEnforcementNone), "": default: - errs = append(errs, fmt.Errorf("invalid `--crd-upgrade-safety-enforcement` %s: must be one of: %v", o.CRDUpgradeSafetyEnforcement, + errs = append(errs, fmt.Errorf("invalid `--crd-upgrade-safety-enforcement` %q: must be one of: %v", o.CRDUpgradeSafetyEnforcement, []string{string(olmv1.CRDUpgradeSafetyEnforcementStrict), string(olmv1.CRDUpgradeSafetyEnforcementNone)})) } switch o.UpgradeConstraintPolicy { case string(olmv1.UpgradeConstraintPolicyCatalogProvided), string(olmv1.UpgradeConstraintPolicySelfCertified), "": default: - errs = append(errs, fmt.Errorf("invalid `--upgrade-constraint-policy` %s: must be one of: %v", o.UpgradeConstraintPolicy, + errs = append(errs, fmt.Errorf("invalid `--upgrade-constraint-policy` %q: must be one of: %v", o.UpgradeConstraintPolicy, []string{string(olmv1.UpgradeConstraintPolicyCatalogProvided), string(olmv1.UpgradeConstraintPolicySelfCertified)})) } if len(o.CatalogSelector) > 0 { var err error o.ParsedSelector, err = metav1.ParseToLabelSelector(o.CatalogSelector) if err != nil { - errs = append(errs, fmt.Errorf("invalid `--labels` value %s: %v", o.CatalogSelector, err)) + errs = append(errs, fmt.Errorf("invalid `--catalog-selector` value %q: %w", o.CatalogSelector, err)) } } return errors.NewAggregate(errs) @@ -121,9 +149,10 @@ func bindMutableCatalogFlags(fs *pflag.FlagSet, o *mutableCatalogOptions) { fs.IntVar(&o.PollIntervalMinutes, "source-poll-interval-minutes", 0, "the interval in minutes to poll the catalog's source image for new content."+ " Only valid for tag based source image references. Set to 0 or -1 to disable polling.") fs.StringToStringVar(&o.Labels, "labels", map[string]string{}, "labels to add to the catalog. Set a label's value as empty to remove it.") + fs.StringVar(&o.Image, "image", "", "image reference for the catalog source. Leave unset to retain the current image.") } -func (o mutableCatalogOptions) validate() error { +func (o *mutableCatalogOptions) validate() error { var errs []error switch o.AvailabilityMode { case "": @@ -132,14 +161,14 @@ func (o mutableCatalogOptions) validate() error { case "false": o.AvailabilityMode = string(olmv1.AvailabilityModeUnavailable) default: - errs = append(errs, fmt.Errorf("invalid `--labels` value %s: must be one of: [true, false]", o.AvailabilityMode)) + errs = append(errs, fmt.Errorf("invalid `--available` value %q: must be one of: [true, false]", o.AvailabilityMode)) } if o.PollIntervalMinutes > 0 && len(o.Image) > 0 { ref, err := reference.Parse(o.Image) if err != nil { - errs = append(errs, fmt.Errorf("invalid catalog source image %s: %v", o.Image, err)) + errs = append(errs, fmt.Errorf("invalid catalog source image %q: %w", o.Image, err)) } else if len(ref.Digest()) != 0 { - errs = append(errs, fmt.Errorf("cannot specify a non-zero --source-poll-interval-minutes for a digest based catalog image %s", o.Image)) + errs = append(errs, fmt.Errorf("cannot specify a non-zero --source-poll-interval-minutes for a digest based catalog image %q", o.Image)) } } return errors.NewAggregate(errs) diff --git a/internal/cmd/internal/olmv1/printing.go b/internal/cmd/internal/olmv1/printing.go index 8608747..d1e1af8 100644 --- a/internal/cmd/internal/olmv1/printing.go +++ b/internal/cmd/internal/olmv1/printing.go @@ -24,17 +24,13 @@ import ( ) func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterExtension) { - if len(extensions) == 0 { - fmt.Println("No resources found") - return - } switch outputFormat { case "yaml": printer := printers.YAMLPrinter{} - if len(extensions) > 1 { + if len(extensions) != 1 { obj := &olmv1.ClusterExtensionList{Items: extensions} obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, - Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind + "List"}) if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to YAML: %v\n", err) } @@ -46,10 +42,10 @@ func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterEx return case "json": printer := printers.JSONPrinter{} - if len(extensions) > 1 { + if len(extensions) != 1 { obj := &olmv1.ClusterExtensionList{Items: extensions} obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, - Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind}) + Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind + "List"}) if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to JSON: %v\n", err) @@ -62,6 +58,10 @@ func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterEx return default: } + if len(extensions) == 0 { + fmt.Println("No resources found") + return + } tw := tabwriter.NewWriter(os.Stdout, 3, 4, 2, ' ', 0) _, _ = fmt.Fprint(tw, "NAME\tINSTALLED BUNDLE\tVERSION\tSOURCE TYPE\tINSTALLED\tPROGRESSING\tAGE\n") @@ -87,17 +87,13 @@ func printFormattedExtensions(outputFormat string, extensions ...olmv1.ClusterEx } func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalog) { - if len(catalogs) == 0 { - fmt.Println("No resources found") - return - } switch outputFormat { case "yaml": printer := printers.YAMLPrinter{} - if len(catalogs) > 1 { + if len(catalogs) != 1 { obj := &olmv1.ClusterCatalogList{Items: catalogs} obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, - Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalogList"}) if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to YAML: %v\n", err) } @@ -109,10 +105,10 @@ func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalo return case "json": printer := printers.JSONPrinter{} - if len(catalogs) > 1 { + if len(catalogs) != 1 { obj := &olmv1.ClusterCatalogList{Items: catalogs} obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group, - Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"}) + Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalogList"}) if err := printer.PrintObj(obj, os.Stdout); err != nil { fmt.Printf("failed to marshal response to JSON: %v\n", err) } @@ -124,6 +120,10 @@ func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalo return default: } + if len(catalogs) == 0 { + fmt.Println("No resources found") + return + } tw := tabwriter.NewWriter(os.Stdout, 3, 4, 2, ' ', 0) _, _ = fmt.Fprint(tw, "NAME\tAVAILABILITY\tPRIORITY\tLASTUNPACKED\tSERVING\tAGE\n") @@ -131,7 +131,7 @@ func printFormattedCatalogs(outputFormat string, catalogs ...olmv1.ClusterCatalo for _, cat := range catalogs { var lastUnpacked string if cat.Status.LastUnpacked != nil { - duration.HumanDuration(time.Since(cat.Status.LastUnpacked.Time)) + lastUnpacked = duration.HumanDuration(time.Since(cat.Status.LastUnpacked.Time)) } age := time.Since(cat.CreationTimestamp.Time) _, _ = fmt.Fprintf(tw, "%s\t%s\t%d\t%s\t%s\t%s\n", @@ -219,7 +219,7 @@ func printFormattedDeclCfg(w io.Writer, catalogDcfg map[string]*declcfg.Declarat } } if !printedHeaders { - _, _ = fmt.Fprint(tw, "No resources found.\n") + _, _ = fmt.Fprintln(tw, "No resources found") } _ = tw.Flush() } diff --git a/internal/pkg/v1/action/action_suite_test.go b/internal/pkg/v1/action/action_suite_test.go index 8fd6204..659663d 100644 --- a/internal/pkg/v1/action/action_suite_test.go +++ b/internal/pkg/v1/action/action_suite_test.go @@ -143,6 +143,21 @@ func withLabels(labels map[string]string) extensionOpt { } } +func withCRDUpgradePolicy(policy string) extensionOpt { + return func(ext *olmv1.ClusterExtension) { + if ext.Spec.Install == nil { + ext.Spec.Install = &olmv1.ClusterExtensionInstallConfig{} + } + if ext.Spec.Install.Preflight == nil { + ext.Spec.Install.Preflight = &olmv1.PreflightConfig{} + } + if ext.Spec.Install.Preflight.CRDUpgradeSafety == nil { + ext.Spec.Install.Preflight.CRDUpgradeSafety = &olmv1.CRDUpgradeSafetyPreflightConfig{} + } + ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(policy) + } +} + func withCatalogSourceType(sourceType olmv1.SourceType) catalogOpt { return func(catalog *olmv1.ClusterCatalog) { catalog.Spec.Source.Type = sourceType diff --git a/internal/pkg/v1/action/catalog_create.go b/internal/pkg/v1/action/catalog_create.go index bc484b7..8db5790 100644 --- a/internal/pkg/v1/action/catalog_create.go +++ b/internal/pkg/v1/action/catalog_create.go @@ -5,12 +5,11 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" - - "sigs.k8s.io/controller-runtime/pkg/client" ) type CatalogCreate struct { @@ -21,7 +20,7 @@ type CatalogCreate struct { Priority int32 PollIntervalMinutes int Labels map[string]string - Available bool + AvailabilityMode string CleanupTimeout time.Duration DryRun string @@ -49,7 +48,7 @@ func (i *CatalogCreate) Run(ctx context.Context) (*olmv1.ClusterCatalog, error) } var err error - if i.Available { + if i.AvailabilityMode == string(olmv1.AvailabilityModeAvailable) { err = waitUntilCatalogStatusCondition(ctx, i.config.Client, &catalog, olmv1.TypeServing, metav1.ConditionTrue) } else { err = waitUntilCatalogStatusCondition(ctx, i.config.Client, &catalog, olmv1.TypeServing, metav1.ConditionFalse) @@ -82,8 +81,8 @@ func (i *CatalogCreate) buildCatalog() olmv1.ClusterCatalog { AvailabilityMode: olmv1.AvailabilityModeAvailable, }, } - if !i.Available { - catalog.Spec.AvailabilityMode = olmv1.AvailabilityModeUnavailable + if len(i.AvailabilityMode) != 0 { + catalog.Spec.AvailabilityMode = olmv1.AvailabilityMode(i.AvailabilityMode) } if i.PollIntervalMinutes > 0 { catalog.Spec.Source.Image.PollIntervalMinutes = &i.PollIntervalMinutes diff --git a/internal/pkg/v1/action/catalog_create_test.go b/internal/pkg/v1/action/catalog_create_test.go index d812fb7..e0551dd 100644 --- a/internal/pkg/v1/action/catalog_create_test.go +++ b/internal/pkg/v1/action/catalog_create_test.go @@ -44,7 +44,7 @@ var _ = Describe("CatalogCreate", func() { Expect(testClient.Initialize()).To(Succeed()) creator := internalaction.NewCatalogCreate(&action.Configuration{Client: testClient}) - creator.Available = true + creator.AvailabilityMode = string(olmv1.AvailabilityModeAvailable) creator.CatalogName = expectedCatalog.Name creator.ImageSourceRef = expectedCatalog.Spec.Source.Image.Ref creator.Priority = expectedCatalog.Spec.Priority @@ -113,17 +113,18 @@ var _ = Describe("CatalogCreate", func() { Expect(testClient.Initialize()).To(Succeed()) creator := internalaction.NewCatalogCreate(&action.Configuration{Client: testClient}) - creator.Available = true + creator.AvailabilityMode = string(olmv1.AvailabilityModeAvailable) creator.CatalogName = expectedCatalog.Name creator.ImageSourceRef = expectedCatalog.Spec.Source.Image.Ref creator.Priority = expectedCatalog.Spec.Priority creator.Labels = expectedCatalog.Labels creator.PollIntervalMinutes = *expectedCatalog.Spec.Source.Image.PollIntervalMinutes - Expect(creator.Run(context.TODO())).To(Succeed()) + _, err := creator.Run(context.TODO()) + Expect(err).ToNot(HaveOccurred()) Expect(testClient.createCalled).To(Equal(1)) - actualCatalog := &olmv1.ClusterCatalog{TypeMeta: metav1.TypeMeta{Kind: "ClusterCatalog", APIVersion: "olm.operatorframework.io/v1"}} + actualCatalog := &olmv1.ClusterCatalog{TypeMeta: metav1.TypeMeta{Kind: "ClusterCatalog", APIVersion: olmv1.GroupVersion.String()}} Expect(testClient.Client.Get(context.TODO(), types.NamespacedName{Name: catalogName}, actualCatalog)).To(Succeed()) validateCreateCatalog(actualCatalog, &expectedCatalog) }) diff --git a/internal/pkg/v1/action/catalog_delete.go b/internal/pkg/v1/action/catalog_delete.go index 153091d..eaf122f 100644 --- a/internal/pkg/v1/action/catalog_delete.go +++ b/internal/pkg/v1/action/catalog_delete.go @@ -5,10 +5,11 @@ import ( "errors" "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" - "sigs.k8s.io/controller-runtime/pkg/client" ) type CatalogDelete struct { @@ -38,7 +39,10 @@ func (i *CatalogDelete) Run(ctx context.Context) ([]olmv1.ClusterCatalog, error) // delete single, specified catalog if !i.DeleteAll { obj, err := i.deleteCatalog(ctx, i.CatalogName) - return []olmv1.ClusterCatalog{obj}, err + if err != nil { + return nil, err + } + return []olmv1.ClusterCatalog{obj}, nil } // delete all existing catalogs diff --git a/internal/pkg/v1/action/catalog_delete_test.go b/internal/pkg/v1/action/catalog_delete_test.go index 237b27b..f7bbe10 100644 --- a/internal/pkg/v1/action/catalog_delete_test.go +++ b/internal/pkg/v1/action/catalog_delete_test.go @@ -39,9 +39,9 @@ var _ = Describe("CatalogDelete", func() { deleter := internalaction.NewCatalogDelete(&cfg) deleter.CatalogName = "name" deleter.DeleteAll = true - catNames, err := deleter.Run(context.TODO()) + catalogs, err := deleter.Run(context.TODO()) Expect(err).NotTo(BeNil()) - Expect(catNames).To(BeEmpty()) + Expect(catalogs).To(BeEmpty()) validateExistingCatalogs(cfg.Client, []string{"cat1", "cat2"}) }) @@ -51,9 +51,9 @@ var _ = Describe("CatalogDelete", func() { deleter := internalaction.NewCatalogDelete(&cfg) deleter.CatalogName = "does-not-exist" - catNames, err := deleter.Run(context.TODO()) + catalogs, err := deleter.Run(context.TODO()) Expect(err).NotTo(BeNil()) - Expect(catNames).To(BeEmpty()) + Expect(catalogs).To(BeEmpty()) validateExistingCatalogs(cfg.Client, []string{"cat1", "cat2"}) }) @@ -63,9 +63,10 @@ var _ = Describe("CatalogDelete", func() { deleter := internalaction.NewCatalogDelete(&cfg) deleter.CatalogName = "cat2" - catNames, err := deleter.Run(context.TODO()) + catalogs, err := deleter.Run(context.TODO()) Expect(err).To(BeNil()) - Expect(catNames).To(BeEmpty()) + Expect(catalogs).To(HaveLen(1)) + validateCatalogList(catalogs, []string{deleter.CatalogName}) validateExistingCatalogs(cfg.Client, []string{"cat1", "cat3"}) }) @@ -75,9 +76,9 @@ var _ = Describe("CatalogDelete", func() { deleter := internalaction.NewCatalogDelete(&cfg) deleter.DeleteAll = true - catNames, err := deleter.Run(context.TODO()) + catalogs, err := deleter.Run(context.TODO()) Expect(err).NotTo(BeNil()) - Expect(catNames).To(BeEmpty()) + Expect(catalogs).To(BeEmpty()) validateExistingCatalogs(cfg.Client, []string{}) }) @@ -87,9 +88,9 @@ var _ = Describe("CatalogDelete", func() { deleter := internalaction.NewCatalogDelete(&cfg) deleter.DeleteAll = true - catNames, err := deleter.Run(context.TODO()) + catalogs, err := deleter.Run(context.TODO()) Expect(err).To(BeNil()) - Expect(catNames).To(ContainElements([]string{"cat1", "cat2", "cat3"})) + validateCatalogList(catalogs, []string{"cat1", "cat2", "cat3"}) validateExistingCatalogs(cfg.Client, []string{}) }) @@ -102,6 +103,10 @@ func validateExistingCatalogs(c client.Client, wantedNames []string) { catalogs := catalogsList.Items Expect(catalogs).To(HaveLen(len(wantedNames))) + validateCatalogList(catalogs, wantedNames) +} + +func validateCatalogList(catalogs []olmv1.ClusterCatalog, wantedNames []string) { for _, wantedName := range wantedNames { Expect(slices.ContainsFunc(catalogs, func(cat olmv1.ClusterCatalog) bool { return cat.Name == wantedName diff --git a/internal/pkg/v1/action/catalog_get.go b/internal/pkg/v1/action/catalog_get.go index 0333acf..8fdb163 100644 --- a/internal/pkg/v1/action/catalog_get.go +++ b/internal/pkg/v1/action/catalog_get.go @@ -16,7 +16,7 @@ type CatalogInstalledGet struct { config *action.Configuration CatalogName string - Selector string + Selector labels.Selector Logf func(string, ...interface{}) } @@ -45,12 +45,8 @@ func (i *CatalogInstalledGet) Run(ctx context.Context) ([]olmv1.ClusterCatalog, // list var result olmv1.ClusterCatalogList listOpts := &client.ListOptions{} - if len(i.Selector) > 0 { - selector, err := labels.Parse(i.Selector) - if err != nil { - return nil, err - } - listOpts.LabelSelector = selector + if i.Selector != nil { + listOpts.LabelSelector = i.Selector } err := i.config.Client.List(ctx, &result, listOpts) diff --git a/internal/pkg/v1/action/catalog_get_test.go b/internal/pkg/v1/action/catalog_get_test.go index 9e74f92..8561e93 100644 --- a/internal/pkg/v1/action/catalog_get_test.go +++ b/internal/pkg/v1/action/catalog_get_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -93,7 +94,9 @@ var _ = Describe("CatalogInstalledGet", func() { cfg := setupEnv(initCatalogs...) getter := internalaction.NewCatalogInstalledGet(&cfg) - getter.Selector = "foo=bar" + var err error + getter.Selector, err = labels.Parse("foo=bar") + Expect(err).To(BeNil()) catalogs, err := getter.Run(context.TODO()) Expect(err).To(BeNil()) Expect(catalogs).To(HaveLen(2)) diff --git a/internal/pkg/v1/action/catalog_search.go b/internal/pkg/v1/action/catalog_search.go index 8a27912..85cd65d 100644 --- a/internal/pkg/v1/action/catalog_search.go +++ b/internal/pkg/v1/action/catalog_search.go @@ -7,6 +7,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/operator-registry/alpha/declcfg" @@ -19,8 +20,7 @@ type CatalogSearch struct { config *action.Configuration CatalogName string - OutputFormat string - Selector string + Selector labels.Selector ListVersions bool Package string CatalogdNamespace string @@ -40,7 +40,7 @@ func (i *CatalogSearch) Run(ctx context.Context) (map[string]*declcfg.Declarativ if len(i.Timeout) > 0 { catalogListTimeout, err := time.ParseDuration(i.Timeout) if err != nil { - return nil, fmt.Errorf("failed to parse timeout %s: %w", i.Timeout, err) + return nil, fmt.Errorf("failed to parse timeout %q: %w", i.Timeout, err) } i.config.Config.Timeout = catalogListTimeout } @@ -61,8 +61,8 @@ func (i *CatalogSearch) Run(ctx context.Context) (map[string]*declcfg.Declarativ if len(i.CatalogName) != 0 { return nil, fmt.Errorf("failed to query for catalog contents: catalog(s) unhealthy") } - if len(i.Selector) > 0 { - return nil, fmt.Errorf("no serving catalogs matching label selector %v found", i.Selector) + if i.Selector != nil { + return nil, fmt.Errorf("no serving catalogs matching label selector %q found", i.Selector) } return nil, fmt.Errorf("no serving catalogs found") } @@ -94,12 +94,12 @@ func (i *CatalogSearch) Run(ctx context.Context) (map[string]*declcfg.Declarativ if !foundPackage { // package name was specified and query was empty across all available catalogs. if len(i.CatalogName) != 0 { - return nil, fmt.Errorf("package %s was not found in ClusterCatalog %s", i.Package, i.CatalogName) + return nil, fmt.Errorf("package %q was not found in ClusterCatalog %q", i.Package, i.CatalogName) } - if len(i.Selector) > 0 { - return nil, fmt.Errorf("package %s was not found in ClusterCatalogs matching label %s", i.Package, i.Selector) + if i.Selector != nil { + return nil, fmt.Errorf("package %q was not found in ClusterCatalogs matching label %q", i.Package, i.Selector) } - return nil, fmt.Errorf("package %s was not found in any serving ClusterCatalog", i.Package) + return nil, fmt.Errorf("package %q was not found in any serving ClusterCatalog", i.Package) } return catalogDeclCfg, nil } diff --git a/internal/pkg/v1/action/catalog_search_test.go b/internal/pkg/v1/action/catalog_search_test.go deleted file mode 100644 index 3ed1705..0000000 --- a/internal/pkg/v1/action/catalog_search_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package action_test - -// import ( - -// . "github.com/onsi/ginkgo" -// . "github.com/onsi/gomega" - -// "fmt" -// "time" - -// v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action" -// "github.com/operator-framework/kubectl-operator/pkg/action" -// olmv1 "github.com/operator-framework/operator-controller/api/v1" -// corev1 "k8s.io/api/core/v1" -// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -// "k8s.io/apimachinery/pkg/util/intstr" -// "k8s.io/client-go/rest" -// "sigs.k8s.io/controller-runtime/pkg/client/fake" -// ) - -// var _ = Describe("", func() { -// catalogdNamespace := "test" -// var serviceName, serviceNamespace, podName, catalogName string -// var servicePort, podPort int32 -// var serverHost, serverPort string - -// catalog := olmv1.ClusterCatalog{ -// Status: olmv1.ClusterCatalogStatus{ -// Conditions: []metav1.Condition{{ -// Type: olmv1.TypeServing, -// Status: metav1.ConditionTrue, -// }}, -// URLs: &olmv1.ClusterCatalogURLs{ -// Base: fmt.Sprintf("http://%s.%s:%d", serviceName, serviceNamespace, servicePort), //port optional if scheme present -// }, -// }, -// } -// secret := corev1.Secret{ -// Data: map[string][]byte{ -// "ca.crt": []byte{},//AppendCertsFromPEM -// }, -// ObjectMeta: metav1.ObjectMeta{ -// Name: "catalogd-*", -// Namespace: catalogdNamespace, -// }, -// } -// svc := corev1.Service{ -// ObjectMeta: metav1.ObjectMeta{ -// Name: serviceName, -// Namespace: serviceNamespace, -// }, -// Spec: corev1.ServiceSpec{ -// Ports: []corev1.ServicePort{{ -// Port: int32(servicePort), -// TargetPort: intstr.IntOrString{IntVal: podPort}, -// }}, -// }, -// } -// endpoints := corev1.Endpoints{ -// ObjectMeta: metav1.ObjectMeta{ -// Name: serviceName, -// Namespace: serviceNamespace, -// }, -// Subsets: []corev1.EndpointSubset{{ -// Addresses: []corev1.EndpointAddress{{ -// TargetRef: &corev1.ObjectReference{ -// Name: fmt.Sprintf("%s", podName), -// }, -// }}, -// }}, -// } -// scheme, err := action.NewScheme() -// Expect(err).ShouldNot(HaveOccurred()) -// fakeClientBuilder := fake.NewClientBuilder() -// fakeClientBuilder.WithScheme(scheme) -// fakeClientBuilder.WithObjects(&catalog, &secret, &svc, &endpoints) -// cfg := &action.Configuration { -// Config: &rest.Config{ -// Host: "localhost", -// APIPath: "", -// Timeout: 1*time.Minute, -// TLSClientConfig: rest.TLSClientConfig{ -// ServerName: "", -// NextProtos: []string{}, -// CAData: []byte{}, //certData, keyData not here? -// }, - -// }, -// Client: fakeClientBuilder.Build(), -// Scheme: scheme, -// } -// searchCmd := v1action.NewCatalogSearch(cfg) -// searchCmd.Timeout = "1m" -// searchCmd.CatalogName = catalogName -// BeforeEach(func(){ - -// }) -// It("", func() { -// Expect("") -// }) -// // server: localhost: fmt.Sprintf("%s/api/v1/namespaces/%s/pods/%s/portforward", c.cfg.Host, namespace, podName); -// // ports: []string{fmt.Sprintf("0:%d", podPort)}, -// // protocol := resp.Header.Get(httpstream.HeaderProtocolVersion) //must equal PortForwardProtocolV1Name - -// }) - -// func newServer(host string, port int) { - -// } diff --git a/internal/pkg/v1/action/catalog_update.go b/internal/pkg/v1/action/catalog_update.go index 96c5a70..b2b0f45 100644 --- a/internal/pkg/v1/action/catalog_update.go +++ b/internal/pkg/v1/action/catalog_update.go @@ -6,12 +6,11 @@ import ( "regexp" "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/ptr" + "sigs.k8s.io/controller-runtime/pkg/client" olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" - "sigs.k8s.io/controller-runtime/pkg/client" ) type CatalogUpdate struct { @@ -32,10 +31,8 @@ type CatalogUpdate struct { func NewCatalogUpdate(config *action.Configuration) *CatalogUpdate { return &CatalogUpdate{ - config: config, - Logf: func(string, ...interface{}) {}, - PollIntervalMinutes: ptr.To(0), - Priority: ptr.To(int32(0)), + config: config, + Logf: func(string, ...interface{}) {}, } } diff --git a/internal/pkg/v1/action/extension_delete.go b/internal/pkg/v1/action/extension_delete.go index 154c325..6c17e73 100644 --- a/internal/pkg/v1/action/extension_delete.go +++ b/internal/pkg/v1/action/extension_delete.go @@ -5,10 +5,11 @@ import ( "errors" "fmt" + "sigs.k8s.io/controller-runtime/pkg/client" + olmv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/kubectl-operator/pkg/action" - "sigs.k8s.io/controller-runtime/pkg/client" ) // ExtensionDeletion deletes an extension or all extensions in the cluster diff --git a/internal/pkg/v1/action/extension_delete_test.go b/internal/pkg/v1/action/extension_delete_test.go index 5b4f4af..520a949 100644 --- a/internal/pkg/v1/action/extension_delete_test.go +++ b/internal/pkg/v1/action/extension_delete_test.go @@ -39,9 +39,9 @@ var _ = Describe("ExtensionDelete", func() { deleter := internalaction.NewExtensionDelete(&cfg) deleter.ExtensionName = "foo" deleter.DeleteAll = true - extNames, err := deleter.Run(context.TODO()) + extensions, err := deleter.Run(context.TODO()) Expect(err).NotTo(BeNil()) - Expect(extNames).To(BeEmpty()) + Expect(extensions).To(BeEmpty()) validateExistingExtensions(cfg.Client, []string{"ext1", "ext2"}) }) @@ -51,9 +51,10 @@ var _ = Describe("ExtensionDelete", func() { deleter := internalaction.NewExtensionDelete(&cfg) deleter.ExtensionName = "does-not-exist" - extNames, err := deleter.Run(context.TODO()) + extensions, err := deleter.Run(context.TODO()) Expect(err).NotTo(BeNil()) - Expect(extNames).To(BeEmpty()) + Expect(extensions).To(HaveLen(1)) + validateExtensionList(extensions, []string{deleter.ExtensionName}) validateExistingExtensions(cfg.Client, []string{"ext1", "ext2"}) }) @@ -74,9 +75,9 @@ var _ = Describe("ExtensionDelete", func() { deleter := internalaction.NewExtensionDelete(&cfg) deleter.DeleteAll = true - extNames, err := deleter.Run(context.TODO()) + extensions, err := deleter.Run(context.TODO()) Expect(err).NotTo(BeNil()) - Expect(extNames).To(BeEmpty()) + Expect(extensions).To(BeEmpty()) validateExistingExtensions(cfg.Client, []string{}) }) @@ -86,9 +87,9 @@ var _ = Describe("ExtensionDelete", func() { deleter := internalaction.NewExtensionDelete(&cfg) deleter.DeleteAll = true - extNames, err := deleter.Run(context.TODO()) + extensions, err := deleter.Run(context.TODO()) Expect(err).To(BeNil()) - Expect(extNames).To(ContainElements([]string{"ext1", "ext2", "ext3"})) + validateExtensionList(extensions, []string{"ext1", "ext2", "ext3"}) validateExistingExtensions(cfg.Client, []string{}) }) @@ -103,6 +104,10 @@ func validateExistingExtensions(c client.Client, wantedNames []string) { extensions := extensionList.Items Expect(extensions).To(HaveLen(len(wantedNames))) + validateExtensionList(extensions, wantedNames) +} + +func validateExtensionList(extensions []olmv1.ClusterExtension, wantedNames []string) { for _, wantedName := range wantedNames { Expect(slices.ContainsFunc(extensions, func(ext olmv1.ClusterExtension) bool { return ext.Name == wantedName diff --git a/internal/pkg/v1/action/extension_install.go b/internal/pkg/v1/action/extension_install.go index c533082..8af75a9 100644 --- a/internal/pkg/v1/action/extension_install.go +++ b/internal/pkg/v1/action/extension_install.go @@ -154,7 +154,7 @@ func (i *ExtensionInstall) cleanup(ctx context.Context) error { }, } if err := waitForDeletion(ctx, i.config.Client, clusterExtension); err != nil { - return fmt.Errorf("delete clusterextension %q: %v", i.ExtensionName, err) + return fmt.Errorf("delete clusterextension %q: %w", i.ExtensionName, err) } return nil } diff --git a/internal/pkg/v1/action/extension_update.go b/internal/pkg/v1/action/extension_update.go index 80e9081..85e0223 100644 --- a/internal/pkg/v1/action/extension_update.go +++ b/internal/pkg/v1/action/extension_update.go @@ -7,6 +7,7 @@ import ( "slices" "time" + "github.com/blang/semver/v4" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -57,12 +58,17 @@ func (i *ExtensionUpdate) Run(ctx context.Context) (*olmv1.ClusterExtension, err i.setDefaults(ext) - constraintPolicy := olmv1.UpgradeConstraintPolicy(i.UpgradeConstraintPolicy) - if !i.needsUpdate(ext, constraintPolicy) { + if i.Version != "" { + if _, err = semver.ParseRange(i.Version); err != nil { + return nil, fmt.Errorf("failed parsing version: %w", err) + } + } + + if !i.needsUpdate(ext) { return nil, ErrNoChange } - i.prepareUpdatedExtension(&ext, constraintPolicy) + i.prepareUpdatedExtension(&ext) if i.DryRun == DryRunAll { if err := i.config.Client.Update(ctx, &ext, client.DryRunAll); err != nil { return nil, err @@ -105,7 +111,8 @@ func (i *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { if i.UpgradeConstraintPolicy == "" { i.UpgradeConstraintPolicy = string(catalogSrc.UpgradeConstraintPolicy) } - if i.CRDUpgradeSafetyEnforcement == "" { + if i.CRDUpgradeSafetyEnforcement == "" && ext.Spec.Install != nil && ext.Spec.Install.Preflight != nil && + ext.Spec.Install.Preflight.CRDUpgradeSafety != nil { i.CRDUpgradeSafetyEnforcement = string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) } if len(i.Labels) == 0 { @@ -116,7 +123,7 @@ func (i *ExtensionUpdate) setDefaults(ext olmv1.ClusterExtension) { } } -func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) bool { +func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension) bool { catalogSrc := ext.Spec.Source.Catalog // object string form is used for comparison to: @@ -126,11 +133,17 @@ func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPoli (catalogSrc.Selector != nil && i.CatalogSelector != nil && catalogSrc.Selector.String() == i.CatalogSelector.String()) + var crdUpgradeSafetyEnforcement string + if ext.Spec.Install != nil && ext.Spec.Install.Preflight != nil && + ext.Spec.Install.Preflight.CRDUpgradeSafety != nil { + crdUpgradeSafetyEnforcement = string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) + } + if catalogSrc.Version == i.Version && slices.Equal(catalogSrc.Channels, i.Channels) && - catalogSrc.UpgradeConstraintPolicy == constraintPolicy && + string(catalogSrc.UpgradeConstraintPolicy) == i.UpgradeConstraintPolicy && maps.Equal(ext.Labels, i.Labels) && - string(ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement) == i.CRDUpgradeSafetyEnforcement && + crdUpgradeSafetyEnforcement == i.CRDUpgradeSafetyEnforcement && sameSelectors { return false } @@ -138,11 +151,24 @@ func (i *ExtensionUpdate) needsUpdate(ext olmv1.ClusterExtension, constraintPoli return true } -func (i *ExtensionUpdate) prepareUpdatedExtension(ext *olmv1.ClusterExtension, constraintPolicy olmv1.UpgradeConstraintPolicy) { - ext.SetLabels(i.Labels) +func (i *ExtensionUpdate) prepareUpdatedExtension(ext *olmv1.ClusterExtension) { + existingLabels := ext.GetLabels() + if existingLabels == nil { + existingLabels = make(map[string]string) + } + if i.Labels != nil { + for k, v := range i.Labels { + if v == "" { + delete(existingLabels, k) + } else { + existingLabels[k] = v + } + } + ext.SetLabels(existingLabels) + } ext.Spec.Source.Catalog.Version = i.Version ext.Spec.Source.Catalog.Selector = i.CatalogSelector ext.Spec.Source.Catalog.Channels = i.Channels - ext.Spec.Source.Catalog.UpgradeConstraintPolicy = constraintPolicy + ext.Spec.Source.Catalog.UpgradeConstraintPolicy = olmv1.UpgradeConstraintPolicy(i.UpgradeConstraintPolicy) ext.Spec.Install.Preflight.CRDUpgradeSafety.Enforcement = olmv1.CRDUpgradeSafetyEnforcement(i.CRDUpgradeSafetyEnforcement) } diff --git a/internal/pkg/v1/action/extension_update_test.go b/internal/pkg/v1/action/extension_update_test.go index 81d1a75..a32f234 100644 --- a/internal/pkg/v1/action/extension_update_test.go +++ b/internal/pkg/v1/action/extension_update_test.go @@ -63,6 +63,7 @@ var _ = Describe("ExtensionUpdate", func() { cfg := setupEnv(buildExtension( "test", withSourceType(olmv1.SourceTypeCatalog), + withCRDUpgradePolicy(string(olmv1.CRDUpgradeSafetyEnforcementStrict)), withConstraintPolicy(string(olmv1.UpgradeConstraintPolicyCatalogProvided))), ) @@ -80,6 +81,7 @@ var _ = Describe("ExtensionUpdate", func() { "test", withSourceType(olmv1.SourceTypeCatalog), withConstraintPolicy(string(olmv1.UpgradeConstraintPolicyCatalogProvided)), + withCRDUpgradePolicy(string(olmv1.CRDUpgradeSafetyEnforcementStrict)), withChannels("a", "b"), withLabels(map[string]string{"c": "d"}), withVersion("10.0.4"), @@ -99,6 +101,7 @@ var _ = Describe("ExtensionUpdate", func() { cfg := setupEnv(buildExtension( "test", withSourceType(olmv1.SourceTypeCatalog), + withCRDUpgradePolicy(string(olmv1.CRDUpgradeSafetyEnforcementStrict)), withConstraintPolicy(string(olmv1.UpgradeConstraintPolicyCatalogProvided))), ) @@ -116,6 +119,7 @@ var _ = Describe("ExtensionUpdate", func() { testExt := buildExtension( "test", withSourceType(olmv1.SourceTypeCatalog), + withCRDUpgradePolicy(string(olmv1.CRDUpgradeSafetyEnforcementStrict)), withConstraintPolicy(string(olmv1.UpgradeConstraintPolicyCatalogProvided)), ) cfg := setupEnv(testExt) @@ -140,6 +144,7 @@ var _ = Describe("ExtensionUpdate", func() { testExt := buildExtension( "test", withSourceType(olmv1.SourceTypeCatalog), + withCRDUpgradePolicy(string(olmv1.CRDUpgradeSafetyEnforcementNone)), withConstraintPolicy(string(olmv1.UpgradeConstraintPolicyCatalogProvided)), ) cfg := setupEnv(testExt, buildExtension("test2"), buildExtension("test3")) @@ -157,6 +162,7 @@ var _ = Describe("ExtensionUpdate", func() { updater.Channels = []string{"a", "b"} updater.Labels = map[string]string{"c": "d"} updater.UpgradeConstraintPolicy = string(olmv1.UpgradeConstraintPolicySelfCertified) + updater.CRDUpgradeSafetyEnforcement = string(olmv1.CRDUpgradeSafetyEnforcementStrict) ext, err := updater.Run(context.TODO()) Expect(err).To(BeNil()) diff --git a/internal/pkg/v1/action/helpers.go b/internal/pkg/v1/action/helpers.go index ac75835..8e3be29 100644 --- a/internal/pkg/v1/action/helpers.go +++ b/internal/pkg/v1/action/helpers.go @@ -7,13 +7,13 @@ import ( "strings" "time" + "github.com/briandowns/spinner" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/briandowns/spinner" olmv1 "github.com/operator-framework/operator-controller/api/v1" ) @@ -34,7 +34,7 @@ func waitUntilCatalogStatusCondition( conditionType string, conditionStatus metav1.ConditionStatus, ) error { - fmt.Printf("waiting for ClusterCatalog %s to become healthy...\n", catalog.Name) + fmt.Printf("waiting for ClusterCatalog %q to become healthy...\n", catalog.Name) s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) s.Start() defer s.Stop() @@ -61,7 +61,7 @@ func waitUntilExtensionStatusCondition( conditionStatus metav1.ConditionStatus, ) error { s := spinner.New(spinner.CharSets[1], 100*time.Millisecond) - s.Prefix = fmt.Sprintf("waiting for ClusterExtension %s to become healthy...", extension.Name) + s.Prefix = fmt.Sprintf("waiting for ClusterExtension %q to become healthy...", extension.Name) s.Start() defer s.Stop() opKey := objectKeyForObject(extension) @@ -110,7 +110,7 @@ func waitForDeletion(ctx context.Context, cl getter, objs ...client.Object) erro } return false, nil }); err != nil { - return fmt.Errorf("wait for %s %q deleted: %v", lowerKind, key.Name, err) + return fmt.Errorf("wait for %s %q deleted: %w", lowerKind, key.Name, err) } } return nil diff --git a/internal/pkg/v1/client/port_forward.go b/internal/pkg/v1/client/port_forward.go index aab6e42..3a1b64f 100644 --- a/internal/pkg/v1/client/port_forward.go +++ b/internal/pkg/v1/client/port_forward.go @@ -2,12 +2,10 @@ package client import ( "context" - "crypto/rand" "crypto/tls" "crypto/x509" "fmt" "io" - "math/big" "net/http" "net/url" "os" @@ -15,6 +13,7 @@ import ( "strings" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/client-go/rest" "k8s.io/client-go/tools/portforward" @@ -172,7 +171,8 @@ func (c *portForwardClientV1) All(ctx context.Context, cc *olmv1.ClusterCatalog) // Get a pod for a given service func (c *portForwardClient) getPodAndPortForService(ctx context.Context, namespace, serviceName string, servicePort int64) (string, int, error) { svc := corev1.Service{} - if err := c.cl.Get(ctx, client.ObjectKey{Name: serviceName, Namespace: namespace}, &svc); err != nil { + svcKey := client.ObjectKey{Name: serviceName, Namespace: namespace} + if err := c.cl.Get(ctx, svcKey, &svc); err != nil { return "", -1, err } @@ -187,29 +187,24 @@ func (c *portForwardClient) getPodAndPortForService(ctx context.Context, namespa return "", -1, fmt.Errorf("service %q has no port %q", serviceName, servicePort) } - endpoints := corev1.Endpoints{} - if err := c.cl.Get(ctx, client.ObjectKey{Name: serviceName, Namespace: namespace}, &endpoints); err != nil { + ep := discoveryv1.EndpointSliceList{} + err := c.cl.List(ctx, &ep, client.MatchingLabels{discoveryv1.LabelServiceName: serviceName}, client.InNamespace(namespace)) + if err != nil { return "", -1, err } - readyAddresses := []corev1.EndpointAddress{} - for _, subset := range endpoints.Subsets { - readyAddresses = append(readyAddresses, subset.Addresses...) + var pods []string + for _, e := range ep.Items { + for _, a := range e.Endpoints { + pods = append(pods, a.TargetRef.Name) + } } - if len(readyAddresses) == 0 { - return "", -1, fmt.Errorf("no endpoints ready for service %s/%s", namespace, serviceName) + if len(pods) == 0 { + return "", -1, fmt.Errorf("no pods ready for service %q", svcKey) } - randAddress, err := rand.Int(rand.Reader, big.NewInt(int64(len(readyAddresses)))) - if err != nil { - return "", -1, err - } - - address := readyAddresses[randAddress.Int64()] - podName := address.TargetRef.Name - // Select the first pod (or you could add load balancing logic here) - return podName, podPort, nil + return pods[0], podPort, nil } // Port forwarding logic to connect to a pod From be9bdaf1e474fc346cba2566cc7c9686a83857ec Mon Sep 17 00:00:00 2001 From: Ankita Thomas Date: Wed, 3 Dec 2025 16:24:27 -0500 Subject: [PATCH 11/11] fix log formatting Signed-off-by: Ankita Thomas --- internal/cmd/internal/olmv1/catalog_create.go | 8 ++++---- internal/cmd/internal/olmv1/catalog_delete.go | 2 +- internal/cmd/internal/olmv1/catalog_get.go | 4 ++-- internal/cmd/internal/olmv1/catalog_search.go | 4 ++-- internal/cmd/internal/olmv1/catalog_update.go | 4 ++-- internal/cmd/internal/olmv1/extension_delete.go | 4 ++-- internal/cmd/internal/olmv1/extension_get.go | 4 ++-- internal/cmd/internal/olmv1/extension_install.go | 8 ++++---- internal/cmd/internal/olmv1/extension_update.go | 4 ++-- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/internal/cmd/internal/olmv1/catalog_create.go b/internal/cmd/internal/olmv1/catalog_create.go index e27374c..2cd3fb6 100644 --- a/internal/cmd/internal/olmv1/catalog_create.go +++ b/internal/cmd/internal/olmv1/catalog_create.go @@ -20,8 +20,8 @@ type catalogCreateOptions struct { mutableCatalogOptions } -// NewCatalogCreateCmd creates a new catalog, requiring a minimum -// of a name for the new catalog and a source image reference +// NewCatalogCreateCmd returns a command that creates a new catalog. +// At minimum, the catalog name and the source image reference must be provided. func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { i := v1action.NewCatalogCreate(cfg) i.Logf = log.Printf @@ -37,7 +37,7 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { i.ImageSourceRef = args[1] opts.Image = i.ImageSourceRef if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.DryRun = opts.DryRun i.Output = opts.Output @@ -47,7 +47,7 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command { i.PollIntervalMinutes = opts.PollIntervalMinutes catalogObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to create catalog %q: %w", i.CatalogName, err) + log.Fatalf("failed to create catalog %q: %v", i.CatalogName, err) } if len(i.DryRun) == 0 { log.Printf("catalog %q created", i.CatalogName) diff --git a/internal/cmd/internal/olmv1/catalog_delete.go b/internal/cmd/internal/olmv1/catalog_delete.go index 93bd05d..4b0bffc 100644 --- a/internal/cmd/internal/olmv1/catalog_delete.go +++ b/internal/cmd/internal/olmv1/catalog_delete.go @@ -36,7 +36,7 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command { i.CatalogName = args[0] } if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.DryRun = opts.DryRun i.Output = opts.Output diff --git a/internal/cmd/internal/olmv1/catalog_get.go b/internal/cmd/internal/olmv1/catalog_get.go index 079efda..2c007b8 100644 --- a/internal/cmd/internal/olmv1/catalog_get.go +++ b/internal/cmd/internal/olmv1/catalog_get.go @@ -30,12 +30,12 @@ func NewCatalogInstalledGetCmd(cfg *action.Configuration) *cobra.Command { i.CatalogName = args[0] } if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.Selector = opts.ParsedSelector installedCatalogs, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed getting installed catalog(s): %w", err) + log.Fatalf("failed getting installed catalog(s): %v", err) } for i := range installedCatalogs { diff --git a/internal/cmd/internal/olmv1/catalog_search.go b/internal/cmd/internal/olmv1/catalog_search.go index 9a8c95c..bd2df0d 100644 --- a/internal/cmd/internal/olmv1/catalog_search.go +++ b/internal/cmd/internal/olmv1/catalog_search.go @@ -29,12 +29,12 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command { Short: "Search catalogs for installable packages matching parameters", Run: func(cmd *cobra.Command, args []string) { if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.Selector = opts.ParsedSelector catalogContents, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed querying catalog(s): %w", err) + log.Fatalf("failed querying catalog(s): %v", err) } switch opts.Output { case "": diff --git a/internal/cmd/internal/olmv1/catalog_update.go b/internal/cmd/internal/olmv1/catalog_update.go index 77cf70e..569b339 100644 --- a/internal/cmd/internal/olmv1/catalog_update.go +++ b/internal/cmd/internal/olmv1/catalog_update.go @@ -33,7 +33,7 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { i.CatalogName = args[0] if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } if cmd.Flags().Changed("priority") { i.Priority = &opts.Priority @@ -51,7 +51,7 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command { i.Output = opts.Output catalogObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to update catalog: %w", err) + log.Fatalf("failed to update catalog: %v", err) } if len(i.DryRun) == 0 { diff --git a/internal/cmd/internal/olmv1/extension_delete.go b/internal/cmd/internal/olmv1/extension_delete.go index c39963a..ae1d2c9 100644 --- a/internal/cmd/internal/olmv1/extension_delete.go +++ b/internal/cmd/internal/olmv1/extension_delete.go @@ -39,13 +39,13 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command { i.ExtensionName = args[0] } if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.DryRun = opts.DryRun i.Output = opts.Output extensions, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to delete extension: %w", err) + log.Fatalf("failed to delete extension: %v", err) } if len(i.DryRun) == 0 { for _, e := range extensions { diff --git a/internal/cmd/internal/olmv1/extension_get.go b/internal/cmd/internal/olmv1/extension_get.go index 853b683..776ab54 100644 --- a/internal/cmd/internal/olmv1/extension_get.go +++ b/internal/cmd/internal/olmv1/extension_get.go @@ -30,12 +30,12 @@ func NewExtensionInstalledGetCmd(cfg *action.Configuration) *cobra.Command { i.ExtensionName = args[0] } if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.Selector = opts.ParsedSelector installedExtensions, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed getting installed extension(s): %w", err) + log.Fatalf("failed getting installed extension(s): %v", err) } for i := range installedExtensions { diff --git a/internal/cmd/internal/olmv1/extension_install.go b/internal/cmd/internal/olmv1/extension_install.go index 800c3b9..7f019dc 100644 --- a/internal/cmd/internal/olmv1/extension_install.go +++ b/internal/cmd/internal/olmv1/extension_install.go @@ -35,7 +35,7 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.Version = opts.Version i.Channels = opts.Channels @@ -47,7 +47,7 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { i.Output = opts.Output extObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to install extension %q: %w", i.ExtensionName, err) + log.Fatalf("failed to install extension %q: %v", i.ExtensionName, err) } if len(i.DryRun) == 0 { log.Printf("extension %q created", i.ExtensionName) @@ -71,13 +71,13 @@ func NewExtensionInstallCmd(cfg *action.Configuration) *cobra.Command { } func bindExtensionInstallFlags(fs *pflag.FlagSet, i *v1action.ExtensionInstall) { - fs.StringVarP(&i.Namespace.Name, "namespace", "n", "olmv1-system", "namespace to install the extension in.") //infer? + fs.StringVarP(&i.Namespace.Name, "namespace", "n", "olmv1-system", "namespace to install the extension in.") fs.StringVarP(&i.PackageName, "package-name", "p", "", "package name of the extension to install. Required.") fs.StringVarP(&i.ServiceAccount, "service-account", "s", "default", "service account name to use for the extension installation.") fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt.") if err := cobra.MarkFlagRequired(fs, "package-name"); err != nil { - log.Fatalf("failed to process command flags: %w", err) + log.Fatalf("failed to process command flags: %v", err) } } diff --git a/internal/cmd/internal/olmv1/extension_update.go b/internal/cmd/internal/olmv1/extension_update.go index 88e0dc3..3c9c2e1 100644 --- a/internal/cmd/internal/olmv1/extension_update.go +++ b/internal/cmd/internal/olmv1/extension_update.go @@ -33,7 +33,7 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { i.ExtensionName = args[0] if err := opts.validate(); err != nil { - log.Fatalf("failed to parse flags: %w", err) + log.Fatalf("failed to parse flags: %v", err) } i.Version = opts.Version i.Channels = opts.Channels @@ -46,7 +46,7 @@ func NewExtensionUpdateCmd(cfg *action.Configuration) *cobra.Command { i.Output = opts.Output extObj, err := i.Run(cmd.Context()) if err != nil { - log.Fatalf("failed to update extension: %w", err) + log.Fatalf("failed to update extension: %v", err) } if len(i.DryRun) == 0 { log.Printf("extension %q updated", i.ExtensionName)