Skip to content

Commit

Permalink
Merge pull request redpanda-data#23636 from r-vasquez/rpk-license-imp…
Browse files Browse the repository at this point in the history
…rovements

[DEVEX-25] rpk: add license_expired to rpk cluster license info
  • Loading branch information
r-vasquez authored Oct 7, 2024
2 parents 58f68dd + 6bc0f12 commit bc44d15
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 45 deletions.
81 changes: 43 additions & 38 deletions src/go/rpk/pkg/cli/cluster/license/info.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package license

import (
"encoding/json"
"fmt"
"os"
"time"
Expand All @@ -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),
Expand All @@ -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)
Expand All @@ -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
}
13 changes: 6 additions & 7 deletions tests/rptest/tests/rpk_cluster_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit bc44d15

Please sign in to comment.