From 6bc0f12654269c8252a5fe553e68877b3e3ce1c9 Mon Sep 17 00:00:00 2001 From: r-vasquez Date: Fri, 4 Oct 2024 05:38:57 -0700 Subject: [PATCH] rpk: add license_expired to rpk cluster license info This was not working before. This commit fixes that bug and enables the --format flag both with JSON and YAML. --- src/go/rpk/pkg/cli/cluster/license/info.go | 81 ++++++++++++---------- tests/rptest/tests/rpk_cluster_test.py | 13 ++-- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/go/rpk/pkg/cli/cluster/license/info.go b/src/go/rpk/pkg/cli/cluster/license/info.go index 6b7cc4c69c5d..87c65ac80df4 100644 --- a/src/go/rpk/pkg/cli/cluster/license/info.go +++ b/src/go/rpk/pkg/cli/cluster/license/info.go @@ -1,7 +1,6 @@ package license import ( - "encoding/json" "fmt" "os" "time" @@ -14,8 +13,16 @@ import ( "github.com/spf13/cobra" ) +type infoResponse struct { + Organization string `json:"organization" yaml:"organization"` + Type string `json:"type" yaml:"type"` + Expires string `json:"expires" yaml:"expires"` + ExpiresUnix int64 `json:"expires_unix" yaml:"expires_unix"` + Checksum string `json:"checksum_sha256,omitempty" yaml:"checksum_sha256,omitempty"` + Expired bool `json:"license_expired" yaml:"license_expired"` +} + func newInfoCommand(fs afero.Fs, p *config.Params) *cobra.Command { - var format string cmd := &cobra.Command{ Use: "info", Args: cobra.ExactArgs(0), @@ -25,9 +32,12 @@ func newInfoCommand(fs afero.Fs, p *config.Params) *cobra.Command { Organization: Organization the license was generated for. Type: Type of license: free, enterprise, etc. Expires: Expiration date of the license - Version: License schema version. `, Run: func(cmd *cobra.Command, _ []string) { + f := p.Formatter + if h, ok := f.Help(infoResponse{}); ok { + out.Exit(h) + } p, err := p.LoadVirtualProfile(fs) out.MaybeDie(err, "rpk unable to load config: %v", err) config.CheckExitCloudAdmin(p) @@ -37,56 +47,51 @@ func newInfoCommand(fs afero.Fs, p *config.Params) *cobra.Command { info, err := cl.GetLicenseInfo(cmd.Context()) out.MaybeDie(err, "unable to retrieve license info: %v", err) - if !info.Loaded { - if format == "json" { - out.Die("{}") - } else { - out.Die("this cluster is missing a license") - } - } - - if info.Properties != (rpadmin.LicenseProperties{}) { - expired := info.Properties.Expires < 0 - if format == "json" { - tm := time.Unix(info.Properties.Expires, 0).Format("Jan 2 2006") - props, err := json.MarshalIndent(struct { - Organization string `json:"organization"` - Type string `json:"type"` - Expires string `json:"expires"` - Checksum string `json:"checksum_sha256,omitempty"` - Expired bool `json:"license_expired,omitempty"` - }{info.Properties.Organization, info.Properties.Type, tm, info.Properties.Checksum, expired}, "", " ") - out.MaybeDie(err, "unable to print license information as json: %v", err) - fmt.Printf("%s\n", props) - } else { - printLicenseInfo(info.Properties, expired) - } - } else { - out.Die("no license loaded") + out.Die("this cluster is missing a license") } + err = printLicenseInfo(f, info.Properties) + out.MaybeDieErr(err) }, } - - cmd.Flags().StringVar(&format, "format", "text", "Output format (text, json)") + p.InstallFormatFlag(cmd) return cmd } -func printLicenseInfo(p rpadmin.LicenseProperties, expired bool) { +func printLicenseInfo(f config.OutFormatter, props rpadmin.LicenseProperties) error { + ut := time.Unix(props.Expires, 0) + isExpired := ut.Before(time.Now()) + resp := infoResponse{ + Organization: props.Organization, + Type: props.Type, + Expires: ut.Format("Jan 2 2006"), + ExpiresUnix: props.Expires, + Checksum: props.Checksum, + Expired: isExpired, + } + if isText, _, formatted, err := f.Format(resp); !isText { + if err != nil { + return fmt.Errorf("unable to print license info in the required format %q: %v", f.Kind, err) + } + fmt.Println(formatted) + return nil + } + out.Section("LICENSE INFORMATION") licenseFormat := `Organization: %v Type: %v Expires: %v ` - if expired { - licenseFormat += `License Expired: true -` + if isExpired { + licenseFormat += "License Expired: true\n" } - tm := time.Unix(p.Expires, 0) - fmt.Printf(licenseFormat, p.Organization, p.Type, tm.Format("Jan 2 2006")) - diff := time.Until(tm) + fmt.Printf(licenseFormat, resp.Organization, resp.Type, resp.Expires) + + // Warn the user if the License is about to expire (<30 days left). + diff := time.Until(ut) daysLeft := int(diff.Hours() / 24) if daysLeft < 30 && daysLeft >= 0 { fmt.Fprintln(os.Stderr, "warning: your license will expire soon") } + return nil } diff --git a/tests/rptest/tests/rpk_cluster_test.py b/tests/rptest/tests/rpk_cluster_test.py index 2afc6b19442e..1a9221322a79 100644 --- a/tests/rptest/tests/rpk_cluster_test.py +++ b/tests/rptest/tests/rpk_cluster_test.py @@ -272,14 +272,13 @@ def obtain_license(): ) expected_license = { - 'expires': - "Jul 11 2122", - 'organization': - 'redpanda-testing', - 'type': - 'enterprise', + 'expires': "Jul 11 2122", + 'organization': 'redpanda-testing', + 'type': 'enterprise', 'checksum_sha256': - '2730125070a934ca1067ed073d7159acc9975dc61015892308aae186f7455daf' + '2730125070a934ca1067ed073d7159acc9975dc61015892308aae186f7455daf', + 'expires_unix': 4813252273, + 'license_expired': False, } result = json.loads(rp_license) assert expected_license == result, result