forked from k8sgateway/k8sgateway
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* adding license check to glooctl * adding changelog * gentool * glooctl license validate * fix typos, code review * renaming valiation * more typos --------- Co-authored-by: soloio-bulldozer[bot] <48420018+soloio-bulldozer[bot]@users.noreply.github.com>
- Loading branch information
1 parent
df93f5f
commit e8ea626
Showing
17 changed files
with
321 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
changelog: | ||
- type: NEW_FEATURE | ||
issueLink: https://github.com/solo-io/gloo/issues/3520 | ||
resolvesIssue: false | ||
description: >- | ||
Check the validity of Gloo Gateway License using `glooctl license validate --license-key <key>`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
title: "glooctl license" | ||
weight: 5 | ||
--- | ||
## glooctl license | ||
|
||
subcommands for interacting with the license | ||
|
||
### Options | ||
|
||
``` | ||
-h, --help help for license | ||
``` | ||
|
||
### Options inherited from parent commands | ||
|
||
``` | ||
-c, --config string set the path to the glooctl config file (default "<home_directory>/.gloo/glooctl-config.yaml") | ||
--consul-address string address of the Consul server. Use with --use-consul (default "127.0.0.1:8500") | ||
--consul-allow-stale-reads Allows reading using Consul's stale consistency mode. | ||
--consul-datacenter string Datacenter to use. If not provided, the default agent datacenter is used. Use with --use-consul | ||
--consul-root-key string key prefix for for Consul key-value storage. (default "gloo") | ||
--consul-scheme string URI scheme for the Consul server. Use with --use-consul (default "http") | ||
--consul-token string Token is used to provide a per-request ACL token which overrides the agent's default token. Use with --use-consul | ||
-i, --interactive use interactive mode | ||
--kube-context string kube context to use when interacting with kubernetes | ||
--kubeconfig string kubeconfig to use, if not standard one | ||
--use-consul use Consul Key-Value storage as the backend for reading and writing config (VirtualServices, Upstreams, and Proxies) | ||
``` | ||
|
||
### SEE ALSO | ||
|
||
* [glooctl](../glooctl) - CLI for Gloo | ||
* [glooctl license validate](../glooctl_license_validate) - Check Gloo Gateway License Validity | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
title: "glooctl license validate" | ||
weight: 5 | ||
--- | ||
## glooctl license validate | ||
|
||
Check Gloo Gateway License Validity | ||
|
||
### Synopsis | ||
|
||
Checking Gloo Gateway license Validity. | ||
|
||
Usage: `glooctl license validate [--license-key license-key]` | ||
|
||
``` | ||
glooctl license validate [flags] | ||
``` | ||
|
||
### Options | ||
|
||
``` | ||
-h, --help help for validate | ||
--license-key string license key to validate | ||
``` | ||
|
||
### Options inherited from parent commands | ||
|
||
``` | ||
-c, --config string set the path to the glooctl config file (default "<home_directory>/.gloo/glooctl-config.yaml") | ||
--consul-address string address of the Consul server. Use with --use-consul (default "127.0.0.1:8500") | ||
--consul-allow-stale-reads Allows reading using Consul's stale consistency mode. | ||
--consul-datacenter string Datacenter to use. If not provided, the default agent datacenter is used. Use with --use-consul | ||
--consul-root-key string key prefix for for Consul key-value storage. (default "gloo") | ||
--consul-scheme string URI scheme for the Consul server. Use with --use-consul (default "http") | ||
--consul-token string Token is used to provide a per-request ACL token which overrides the agent's default token. Use with --use-consul | ||
-i, --interactive use interactive mode | ||
--kube-context string kube context to use when interacting with kubernetes | ||
--kubeconfig string kubeconfig to use, if not standard one | ||
--use-consul use Consul Key-Value storage as the backend for reading and writing config (VirtualServices, Upstreams, and Proxies) | ||
``` | ||
|
||
### SEE ALSO | ||
|
||
* [glooctl license](../glooctl_license) - subcommands for interacting with the license | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package license | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestLicense(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "License Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package license | ||
|
||
import ( | ||
"github.com/solo-io/gloo/projects/gloo/cli/pkg/cmd/options" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func RootCmd(opts *options.Options) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "license", | ||
Aliases: []string{"l"}, | ||
Short: "subcommands for interacting with the license", | ||
} | ||
cmd.AddCommand(License(opts)) | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package license | ||
|
||
import ( | ||
"encoding/base64" | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/golang-jwt/jwt/v4" | ||
"github.com/solo-io/gloo/projects/gloo/cli/pkg/cmd/options" | ||
"github.com/solo-io/gloo/projects/gloo/cli/pkg/flagutils" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type AddOn struct { | ||
Addon int `json:"Addon"` | ||
ExpiresAt int64 `json:"ExpiresAt"` | ||
LicenseType string `json:"LicenseType"` | ||
} | ||
|
||
type LicenseClaims struct { | ||
AddOns []AddOn `json:"addOns"` | ||
ExpirationDate int64 `json:"exp"` | ||
CreationDate int64 `json:"iat"` | ||
LicenseType string `json:"lt"` | ||
Product string `json:"product"` | ||
jwt.RegisteredClaims | ||
} | ||
|
||
type LicenseLegacyClaims struct { | ||
AddOns string `json:"addOns"` | ||
Exp int64 `json:"exp"` | ||
Iat int64 `json:"iat"` | ||
Key string `json:"k"` | ||
LicType string `json:"lt"` | ||
Product string `json:"product"` | ||
jwt.RegisteredClaims | ||
} | ||
|
||
func License(opts *options.Options) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "validate", | ||
Aliases: []string{"v", "validate"}, | ||
Short: "Check Gloo Gateway License Validity", | ||
Long: "Checking Gloo Gateway license Validity.\n\n" + | ||
"" + | ||
"Usage: `glooctl license validate [--license-key license-key]`", | ||
|
||
RunE: func(cmd *cobra.Command, args []string) error { | ||
licenseKey := opts.ValidateLicense.LicenseKey | ||
if strings.Count(licenseKey, ".") == 1 { | ||
return validateLegacyLicense(opts.ValidateLicense.LicenseKey) | ||
} | ||
return validateLicense(opts.ValidateLicense.LicenseKey) | ||
|
||
}} | ||
flags := cmd.Flags() | ||
flagutils.AddLicenseValidationFlag(flags, &opts.ValidateLicense.LicenseKey) | ||
cmd.MarkFlagRequired(flagutils.LicenseFlag) | ||
return cmd | ||
} | ||
|
||
func validateLicense(licenseKey string) error { | ||
var licenseClaims LicenseClaims | ||
|
||
_, _, err := new(jwt.Parser).ParseUnverified(licenseKey, &licenseClaims) | ||
if err != nil { | ||
return fmt.Errorf("can't parse license key") | ||
} | ||
fmt.Printf(formatLicenseDetail(licenseClaims.CreationDate, licenseClaims.ExpirationDate, licenseClaims.Product, licenseClaims.LicenseType == "trial")) | ||
return nil | ||
} | ||
|
||
func validateLegacyLicense(licenseKey string) error { | ||
var licenseLegacyClaim LicenseLegacyClaims | ||
var standardizedLicenseKey = base64.RawURLEncoding.EncodeToString([]byte(`{"alg":"HS256","typ":"JWT"}`)) + "." + licenseKey | ||
_, _, err := new(jwt.Parser).ParseUnverified(standardizedLicenseKey, &licenseLegacyClaim) | ||
if err != nil { | ||
return fmt.Errorf("can't parse license key") | ||
} | ||
fmt.Printf(formatLicenseDetail(licenseLegacyClaim.Iat, licenseLegacyClaim.Exp, licenseLegacyClaim.Product, licenseLegacyClaim.LicType == "trial")) | ||
return nil | ||
} | ||
|
||
func formatLicenseDetail(creationTime int64, expirationTime int64, product string, isTrial bool) string { | ||
var productName = "unknown" | ||
switch product { | ||
case "gloo": | ||
productName = "Gloo Gateway" | ||
} | ||
var res = "" | ||
if isTrial { | ||
res += fmt.Sprintln("This a trial license for", productName) | ||
} else { | ||
res += fmt.Sprintln("This an enterprise license for", productName) | ||
} | ||
res += fmt.Sprintln("This license was created on:", time.Unix(creationTime, 0)) | ||
if expirationTime < time.Now().Unix() { | ||
res += fmt.Sprintln("This license is expired since:", time.Unix(expirationTime, 0)) | ||
} else { | ||
res += fmt.Sprintln("This license is valid until:", time.Unix(expirationTime, 0)) | ||
} | ||
|
||
return res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package license | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/golang-jwt/jwt/v4" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("License Validate", func() { | ||
|
||
licenseClaims := LicenseClaims{ | ||
AddOns: []AddOn{{Addon: 1, ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), LicenseType: "trial"}}, | ||
ExpirationDate: time.Now().Add(24 * time.Hour).Unix(), | ||
CreationDate: time.Now().Add(-24 * time.Hour).Unix(), | ||
LicenseType: "trial", | ||
Product: "gloo", | ||
} | ||
|
||
expiredLicenseClaims := LicenseClaims{ | ||
AddOns: []AddOn{{Addon: 1, ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), LicenseType: "trial"}}, | ||
ExpirationDate: time.Now().Add(-24 * time.Hour).Unix(), | ||
CreationDate: time.Now().Add(-48 * time.Hour).Unix(), | ||
LicenseType: "ent", | ||
Product: "gloo", | ||
} | ||
|
||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, licenseClaims) | ||
tokenString, err := token.SignedString([]byte("secret")) | ||
|
||
It("should verify a valid license", func() { | ||
err = validateLicense(tokenString) | ||
Expect(err).ToNot(HaveOccurred()) | ||
}) | ||
|
||
It("should fail to verify an invalid license", func() { | ||
invalidLicenseKey := "invalid" | ||
|
||
err := validateLicense(invalidLicenseKey) | ||
Expect(err).To(HaveOccurred()) | ||
Expect(err.Error()).To(Equal("can't parse license key")) | ||
}) | ||
|
||
It("should print correct values for valid license", func() { | ||
|
||
res := formatLicenseDetail(licenseClaims.CreationDate, licenseClaims.ExpirationDate, licenseClaims.Product, licenseClaims.LicenseType == "trial") | ||
Expect(res).To(ContainSubstring("This a trial license")) | ||
Expect(res).To(ContainSubstring("This license is valid until")) | ||
}) | ||
|
||
It("should print correct values for expired license", func() { | ||
|
||
res := formatLicenseDetail(expiredLicenseClaims.CreationDate, expiredLicenseClaims.ExpirationDate, expiredLicenseClaims.Product, expiredLicenseClaims.LicenseType == "trial") | ||
Expect(res).To(ContainSubstring("This an enterprise license for Gloo Gateway")) | ||
Expect(res).To(ContainSubstring("This license is expired since")) | ||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.