From 11010d180fea67ade4d7d3a3ce7c91eb4c0f1e4f Mon Sep 17 00:00:00 2001 From: bbernays Date: Mon, 2 Sep 2024 15:55:35 -0500 Subject: [PATCH 01/17] deps --- examples/simple_plugin/go.mod | 1 + examples/simple_plugin/go.sum | 2 ++ go.mod | 1 + go.sum | 2 ++ 4 files changed, 6 insertions(+) diff --git a/examples/simple_plugin/go.mod b/examples/simple_plugin/go.mod index 343f6295a0..0595f0604a 100644 --- a/examples/simple_plugin/go.mod +++ b/examples/simple_plugin/go.mod @@ -21,6 +21,7 @@ require ( github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect + github.com/aws/aws-sdk-go-v2/service/licensemanager v1.27.4 // indirect github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.23.4 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect diff --git a/examples/simple_plugin/go.sum b/examples/simple_plugin/go.sum index ff9ae083ec..b6004d539b 100644 --- a/examples/simple_plugin/go.sum +++ b/examples/simple_plugin/go.sum @@ -25,6 +25,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbL github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= +github.com/aws/aws-sdk-go-v2/service/licensemanager v1.27.4 h1:8tRjT7S8LxBRNRP3KtdV9vj9dJPzG1yDvRIqVmznZII= +github.com/aws/aws-sdk-go-v2/service/licensemanager v1.27.4/go.mod h1:AhruhNzkEGM6NxQzGhc0gWvaj/o8FZi/cCoGymOVxyo= github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.23.4 h1:I9yxA99P3rbkzhv8iDykQcel7n03PmlK8GO6NDpOkj0= github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.23.4/go.mod h1:YAiuhtKyLLPdouuDXeFWh4nrDrMqwQqukNvDSyhltbU= github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= diff --git a/go.mod b/go.mod index 8c2158fc3c..a83999af54 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/apache/arrow/go/v17 v17.0.0 github.com/aws/aws-sdk-go-v2 v1.30.4 github.com/aws/aws-sdk-go-v2/config v1.27.30 + github.com/aws/aws-sdk-go-v2/service/licensemanager v1.27.4 github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.23.4 github.com/bradleyjkemp/cupaloy/v2 v2.8.0 github.com/cloudquery/cloudquery-api-go v1.13.0 diff --git a/go.sum b/go.sum index 7352428f41..c5e7e534f6 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbL github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= +github.com/aws/aws-sdk-go-v2/service/licensemanager v1.27.4 h1:8tRjT7S8LxBRNRP3KtdV9vj9dJPzG1yDvRIqVmznZII= +github.com/aws/aws-sdk-go-v2/service/licensemanager v1.27.4/go.mod h1:AhruhNzkEGM6NxQzGhc0gWvaj/o8FZi/cCoGymOVxyo= github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.23.4 h1:I9yxA99P3rbkzhv8iDykQcel7n03PmlK8GO6NDpOkj0= github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.23.4/go.mod h1:YAiuhtKyLLPdouuDXeFWh4nrDrMqwQqukNvDSyhltbU= github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= From 3fff028a3e0687fa78563dcfb4557df05b159f4d Mon Sep 17 00:00:00 2001 From: bbernays Date: Mon, 2 Sep 2024 15:55:41 -0500 Subject: [PATCH 02/17] Create licensemanager.go --- premium/mocks/licensemanager.go | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 premium/mocks/licensemanager.go diff --git a/premium/mocks/licensemanager.go b/premium/mocks/licensemanager.go new file mode 100644 index 0000000000..818ad27cb8 --- /dev/null +++ b/premium/mocks/licensemanager.go @@ -0,0 +1,56 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: offline.go + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + licensemanager "github.com/aws/aws-sdk-go-v2/service/licensemanager" + gomock "github.com/golang/mock/gomock" +) + +// MockAWSLicenseManagerInterface is a mock of AWSLicenseManagerInterface interface. +type MockAWSLicenseManagerInterface struct { + ctrl *gomock.Controller + recorder *MockAWSLicenseManagerInterfaceMockRecorder +} + +// MockAWSLicenseManagerInterfaceMockRecorder is the mock recorder for MockAWSLicenseManagerInterface. +type MockAWSLicenseManagerInterfaceMockRecorder struct { + mock *MockAWSLicenseManagerInterface +} + +// NewMockAWSLicenseManagerInterface creates a new mock instance. +func NewMockAWSLicenseManagerInterface(ctrl *gomock.Controller) *MockAWSLicenseManagerInterface { + mock := &MockAWSLicenseManagerInterface{ctrl: ctrl} + mock.recorder = &MockAWSLicenseManagerInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAWSLicenseManagerInterface) EXPECT() *MockAWSLicenseManagerInterfaceMockRecorder { + return m.recorder +} + +// CheckoutLicense mocks base method. +func (m *MockAWSLicenseManagerInterface) CheckoutLicense(ctx context.Context, params *licensemanager.CheckoutLicenseInput, optFns ...func(*licensemanager.Options)) (*licensemanager.CheckoutLicenseOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, params} + for _, a := range optFns { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CheckoutLicense", varargs...) + ret0, _ := ret[0].(*licensemanager.CheckoutLicenseOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CheckoutLicense indicates an expected call of CheckoutLicense. +func (mr *MockAWSLicenseManagerInterfaceMockRecorder) CheckoutLicense(ctx, params interface{}, optFns ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, params}, optFns...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckoutLicense", reflect.TypeOf((*MockAWSLicenseManagerInterface)(nil).CheckoutLicense), varargs...) +} From 2a23b1198eab737e036e94d8129bf0407ff2c0dc Mon Sep 17 00:00:00 2001 From: bbernays Date: Mon, 2 Sep 2024 15:56:51 -0500 Subject: [PATCH 03/17] Update offline.go --- premium/offline.go | 117 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 11 deletions(-) diff --git a/premium/offline.go b/premium/offline.go index 5d3ea56b44..24074f934b 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -1,18 +1,25 @@ package premium import ( + "context" "crypto/ed25519" _ "embed" "encoding/hex" "encoding/json" "errors" + "fmt" "os" "path/filepath" "slices" "strings" "time" + "github.com/aws/aws-sdk-go-v2/aws" + awsConfig "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/licensemanager" + "github.com/aws/aws-sdk-go-v2/service/licensemanager/types" "github.com/cloudquery/plugin-sdk/v4/plugin" + "github.com/google/uuid" "github.com/rs/zerolog" ) @@ -41,20 +48,83 @@ var publicKey string var timeFunc = time.Now -func ValidateLicense(logger zerolog.Logger, meta plugin.Meta, licenseFileOrDirectory string) error { - fi, err := os.Stat(licenseFileOrDirectory) +//go:generate mockgen -package=mocks -destination=../premium/mocks/licensemanager.go -source=offline.go AWSLicenseManagerInterface +type AWSLicenseManagerInterface interface { + CheckoutLicense(ctx context.Context, params *licensemanager.CheckoutLicenseInput, optFns ...func(*licensemanager.Options)) (*licensemanager.CheckoutLicenseOutput, error) +} + +type CQLicenseClient struct { + logger zerolog.Logger + meta plugin.Meta + licenseFileOrDirectory string + awsLicenseManagerClient AWSLicenseManagerInterface +} + +type LicenseClientOptions func(updater *CQLicenseClient) + +func WithMeta(meta plugin.Meta) LicenseClientOptions { + return func(cl *CQLicenseClient) { + cl.meta = meta + } +} + +func WithLicenseFileOrDirectory(licenseFileOrDirectory string) LicenseClientOptions { + return func(cl *CQLicenseClient) { + cl.licenseFileOrDirectory = licenseFileOrDirectory + } +} + +func WithAWSLicenseManagerClient(awsLicenseManagerClient AWSLicenseManagerInterface) LicenseClientOptions { + return func(cl *CQLicenseClient) { + cl.awsLicenseManagerClient = awsLicenseManagerClient + } +} + +func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...LicenseClientOptions) (CQLicenseClient, error) { + cl := &CQLicenseClient{ + logger: logger, + } + + for _, op := range ops { + op(cl) + } + + if cl.awsLicenseManagerClient == nil { + cfg, err := awsConfig.LoadDefaultConfig(ctx) + if err != nil { + return *cl, fmt.Errorf("failed to load AWS config: %w", err) + } + cl.awsLicenseManagerClient = licensemanager.NewFromConfig(cfg) + } + + return *cl, nil +} + +func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { + // License can be provided via environment variable for AWS Marketplace or CLI flag + if lc.licenseFileOrDirectory == "" && os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") == "" { + return ErrLicenseNotApplicable + } + if os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") != "" { + return lc.validateMarketplaceLicense(ctx) + } + return lc.validateCQLicense() +} + +func (lc CQLicenseClient) validateCQLicense() error { + fi, err := os.Stat(lc.licenseFileOrDirectory) if err != nil { return err } if !fi.IsDir() { - return validateLicenseFile(logger, meta, licenseFileOrDirectory) + return lc.validateLicenseFile(lc.licenseFileOrDirectory) } found := false var lastError error - err = filepath.WalkDir(licenseFileOrDirectory, func(path string, d os.DirEntry, err error) error { + err = filepath.WalkDir(lc.licenseFileOrDirectory, func(path string, d os.DirEntry, err error) error { if d.IsDir() { - if path == licenseFileOrDirectory { + if path == lc.licenseFileOrDirectory { return nil } return filepath.SkipDir @@ -67,8 +137,8 @@ func ValidateLicense(logger zerolog.Logger, meta plugin.Meta, licenseFileOrDirec return nil } - logger.Debug().Str("path", path).Msg("considering license file") - lastError = validateLicenseFile(logger, meta, path) + lc.logger.Debug().Str("path", path).Msg("considering license file") + lastError = lc.validateLicenseFile(path) switch lastError { case nil: found = true @@ -91,7 +161,7 @@ func ValidateLicense(logger zerolog.Logger, meta plugin.Meta, licenseFileOrDirec return errors.New("failed to validate license directory") } -func validateLicenseFile(logger zerolog.Logger, meta plugin.Meta, licenseFile string) error { +func (lc CQLicenseClient) validateLicenseFile(licenseFile string) error { licenseContents, err := os.ReadFile(licenseFile) if err != nil { return err @@ -103,14 +173,14 @@ func validateLicenseFile(logger zerolog.Logger, meta plugin.Meta, licenseFile st } if len(l.Plugins) > 0 { - ref := strings.Join([]string{meta.Team, string(meta.Kind), meta.Name}, "/") - teamRef := meta.Team + "/*" + ref := strings.Join([]string{lc.meta.Team, string(lc.meta.Kind), lc.meta.Name}, "/") + teamRef := lc.meta.Team + "/*" if !slices.Contains(l.Plugins, ref) && !slices.Contains(l.Plugins, teamRef) { return ErrLicenseNotApplicable } } - return l.IsValid(logger) + return l.IsValid(lc.logger) } func UnpackLicense(lic []byte) (*License, error) { @@ -158,3 +228,28 @@ func (l *License) IsValid(logger zerolog.Logger) error { msg.Time("expires_at", l.ExpiresAt).Msgf("Offline license for %s loaded.", l.LicensedTo) return nil } + +func (lc CQLicenseClient) validateMarketplaceLicense(ctx context.Context) error { + clientToken := uuid.New() + + resp, err := lc.awsLicenseManagerClient.CheckoutLicense(ctx, &licensemanager.CheckoutLicenseInput{ + CheckoutType: types.CheckoutTypeProvisional, + ClientToken: aws.String(clientToken.String()), + ProductSKU: aws.String("55ukc0d5qv3gebks148tjr62j"), + Entitlements: []types.EntitlementData{ + { + Name: aws.String("Unlimited"), + Unit: types.EntitlementDataUnitNone, + }, + }, + // This is hardcoded for AWS Marketplace, because this is the only supported value for marketplace licenses + KeyFingerprint: aws.String("aws:294406891311:AWS/Marketplace:issuer-fingerprint"), + }) + if err != nil { + return fmt.Errorf("failed to checkout license: %w", err) + } + if len(resp.EntitlementsAllowed) == 0 { + return errors.New("no entitlements provisioned") + } + return nil +} From 31ddc51966ae5b8c1d5f54a0cd1819c857eda1f3 Mon Sep 17 00:00:00 2001 From: bbernays Date: Mon, 2 Sep 2024 15:56:53 -0500 Subject: [PATCH 04/17] Update offline_test.go --- premium/offline_test.go | 77 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/premium/offline_test.go b/premium/offline_test.go index 8a7685e36b..0cbb56b37b 100644 --- a/premium/offline_test.go +++ b/premium/offline_test.go @@ -1,13 +1,22 @@ package premium import ( + "context" + "fmt" "os" "path/filepath" "testing" "time" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/licensemanager" + "github.com/aws/aws-sdk-go-v2/service/licensemanager/types" + "github.com/cloudquery/plugin-sdk/v4/faker" "github.com/cloudquery/plugin-sdk/v4/plugin" + "github.com/cloudquery/plugin-sdk/v4/premium/mocks" + "github.com/golang/mock/gomock" "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -153,8 +162,9 @@ func licenseTest(inputPath string, meta plugin.Meta, timeIs time.Time, expectErr timeFunc = func() time.Time { return timeIs } - - err := ValidateLicense(zerolog.Nop(), meta, inputPath) + licenseClient, err := NewLicenseClient(context.TODO(), zerolog.Nop(), WithMeta(meta), WithLicenseFileOrDirectory(inputPath)) + require.NoError(t, err) + err = licenseClient.ValidateLicense(context.TODO()) if expectError == nil { require.NoError(t, err) } else { @@ -162,3 +172,66 @@ func licenseTest(inputPath string, meta plugin.Meta, timeIs time.Time, expectErr } } } + +func TestValidateMarketplaceLicense(t *testing.T) { + ctrl := gomock.NewController(t) + m := mocks.NewMockAWSLicenseManagerInterface(ctrl) + out := licensemanager.CheckoutLicenseOutput{} + in := licenseInput{ + CheckoutLicenseInput: licensemanager.CheckoutLicenseInput{ + CheckoutType: types.CheckoutTypeProvisional, + ProductSKU: aws.String("55ukc0d5qv3gebks148tjr62j"), + Entitlements: []types.EntitlementData{ + { + Name: aws.String("Unlimited"), + Unit: types.EntitlementDataUnitNone, + }, + }, + KeyFingerprint: aws.String("aws:294406891311:AWS/Marketplace:issuer-fingerprint"), + }, + } + + assert.NoError(t, faker.FakeObject(&out)) + m.EXPECT().CheckoutLicense(gomock.Any(), in).Return(&out, nil) + t.Setenv("CQ_AWS_MARKETPLACE_LICENSE", "true") + + licenseClient, err := NewLicenseClient(context.TODO(), zerolog.Nop(), WithAWSLicenseManagerClient(m)) + require.NoError(t, err) + require.NoError(t, licenseClient.ValidateLicense(context.TODO())) +} + +type licenseInput struct { + licensemanager.CheckoutLicenseInput +} + +func (li licenseInput) Matches(x any) bool { + testInput, ok := x.(*licensemanager.CheckoutLicenseInput) + if !ok { + return false + } + + if testInput.CheckoutType != li.CheckoutType { + return false + } + + for i, ent := range testInput.Entitlements { + if aws.ToString(ent.Name) != aws.ToString(li.Entitlements[i].Name) { + return false + } + if aws.ToString(ent.Value) != aws.ToString(li.Entitlements[i].Value) { + return false + } + } + + if aws.ToString(testInput.KeyFingerprint) != aws.ToString(li.KeyFingerprint) { + return false + } + if aws.ToString(testInput.ProductSKU) != aws.ToString(li.ProductSKU) { + return false + } + return true +} + +func (li licenseInput) String() string { + return fmt.Sprintf("{CheckoutType:%s Entitlements:%v KeyFingerprint:%s ProductSKU:%s}", li.CheckoutType, li.Entitlements, *li.KeyFingerprint, *li.ProductSKU) +} From 184e963c87ff5c6b7c5c399653e8b087488b4692 Mon Sep 17 00:00:00 2001 From: bbernays Date: Mon, 2 Sep 2024 15:56:55 -0500 Subject: [PATCH 05/17] Update plugin.go --- serve/plugin.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/serve/plugin.go b/serve/plugin.go index 4a6caddd2d..28084acb4b 100644 --- a/serve/plugin.go +++ b/serve/plugin.go @@ -145,15 +145,17 @@ func (s *PluginServe) newCmdPluginServe() *cobra.Command { defer shutdown() } - if licenseFile != "" { - switch err := premium.ValidateLicense(logger, s.plugin.Meta(), licenseFile); err { - case nil: - s.plugin.SetSkipUsageClient(true) - case premium.ErrLicenseNotApplicable: - // no-op: Treat as if no license was provided - default: - return fmt.Errorf("failed to validate license: %w", err) - } + licenseClient, err := premium.NewLicenseClient(cmd.Context(), logger, premium.WithMeta(s.plugin.Meta()), premium.WithLicenseFileOrDirectory(licenseFile)) + if err != nil { + return fmt.Errorf("failed to create license client: %w", err) + } + switch err := licenseClient.ValidateLicense(cmd.Context()); err { + case nil: + s.plugin.SetSkipUsageClient(true) + case premium.ErrLicenseNotApplicable: + // no-op: Treat as if no license was provided + default: + return fmt.Errorf("failed to validate license: %w", err) } var listener net.Listener From 2d9b6050b54c775e0137cb154701e2a8ea027a22 Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 10:53:22 -0500 Subject: [PATCH 06/17] Update offline.go --- premium/offline.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/premium/offline.go b/premium/offline.go index 24074f934b..7d0fd08430 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -81,23 +81,23 @@ func WithAWSLicenseManagerClient(awsLicenseManagerClient AWSLicenseManagerInterf } func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...LicenseClientOptions) (CQLicenseClient, error) { - cl := &CQLicenseClient{ + cl := CQLicenseClient{ logger: logger, } for _, op := range ops { - op(cl) + op(&cl) } if cl.awsLicenseManagerClient == nil { cfg, err := awsConfig.LoadDefaultConfig(ctx) if err != nil { - return *cl, fmt.Errorf("failed to load AWS config: %w", err) + return cl, fmt.Errorf("failed to load AWS config: %w", err) } cl.awsLicenseManagerClient = licensemanager.NewFromConfig(cfg) } - return *cl, nil + return cl, nil } func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { From 760d909abac297042a06264999d227a3e80f1e33 Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 11:49:51 -0500 Subject: [PATCH 07/17] Update offline.go --- premium/offline.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/premium/offline.go b/premium/offline.go index 7d0fd08430..060e2babc7 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -80,6 +80,10 @@ func WithAWSLicenseManagerClient(awsLicenseManagerClient AWSLicenseManagerInterf } } +func isMarketplaceLicense() bool { + return os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") == "true" +} + func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...LicenseClientOptions) (CQLicenseClient, error) { cl := CQLicenseClient{ logger: logger, @@ -89,7 +93,7 @@ func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...License op(&cl) } - if cl.awsLicenseManagerClient == nil { + if isMarketplaceLicense() && cl.awsLicenseManagerClient == nil { cfg, err := awsConfig.LoadDefaultConfig(ctx) if err != nil { return cl, fmt.Errorf("failed to load AWS config: %w", err) @@ -102,10 +106,10 @@ func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...License func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { // License can be provided via environment variable for AWS Marketplace or CLI flag - if lc.licenseFileOrDirectory == "" && os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") == "" { + if lc.licenseFileOrDirectory == "" && !isMarketplaceLicense() { return ErrLicenseNotApplicable } - if os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") != "" { + if isMarketplaceLicense() { return lc.validateMarketplaceLicense(ctx) } return lc.validateCQLicense() From 9f23bac63517f0e1a03fd8d72e6288672a63e44f Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 11:59:39 -0500 Subject: [PATCH 08/17] Update offline.go --- premium/offline.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/premium/offline.go b/premium/offline.go index 060e2babc7..87131b8a76 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -58,6 +58,7 @@ type CQLicenseClient struct { meta plugin.Meta licenseFileOrDirectory string awsLicenseManagerClient AWSLicenseManagerInterface + isMarketplaceLicense bool } type LicenseClientOptions func(updater *CQLicenseClient) @@ -80,20 +81,17 @@ func WithAWSLicenseManagerClient(awsLicenseManagerClient AWSLicenseManagerInterf } } -func isMarketplaceLicense() bool { - return os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") == "true" -} - func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...LicenseClientOptions) (CQLicenseClient, error) { cl := CQLicenseClient{ - logger: logger, + logger: logger, + isMarketplaceLicense: os.Getenv("CQ_AWS_MARKETPLACE_LICENSE") == "true", } for _, op := range ops { op(&cl) } - if isMarketplaceLicense() && cl.awsLicenseManagerClient == nil { + if cl.isMarketplaceLicense && cl.awsLicenseManagerClient == nil { cfg, err := awsConfig.LoadDefaultConfig(ctx) if err != nil { return cl, fmt.Errorf("failed to load AWS config: %w", err) @@ -106,10 +104,10 @@ func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...License func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { // License can be provided via environment variable for AWS Marketplace or CLI flag - if lc.licenseFileOrDirectory == "" && !isMarketplaceLicense() { + if lc.licenseFileOrDirectory == "" && !lc.isMarketplaceLicense { return ErrLicenseNotApplicable } - if isMarketplaceLicense() { + if lc.isMarketplaceLicense { return lc.validateMarketplaceLicense(ctx) } return lc.validateCQLicense() From adade0782434f354c115da087aba6eeece02a8a2 Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:01:55 -0500 Subject: [PATCH 09/17] Update offline.go --- premium/offline.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/premium/offline.go b/premium/offline.go index 87131b8a76..be2a7c0ab5 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -104,13 +104,16 @@ func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...License func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { // License can be provided via environment variable for AWS Marketplace or CLI flag - if lc.licenseFileOrDirectory == "" && !lc.isMarketplaceLicense { - return ErrLicenseNotApplicable - } - if lc.isMarketplaceLicense { + + switch { + case lc.isMarketplaceLicense: return lc.validateMarketplaceLicense(ctx) + case lc.licenseFileOrDirectory != "": + lc.validateCQLicense() + default: + return ErrLicenseNotApplicable } - return lc.validateCQLicense() + } func (lc CQLicenseClient) validateCQLicense() error { From d7df1861618137adc3ee14432b887d9a87c99a90 Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:04:15 -0500 Subject: [PATCH 10/17] Update offline.go --- premium/offline.go | 1 - 1 file changed, 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index be2a7c0ab5..fe0f7a355a 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -104,7 +104,6 @@ func NewLicenseClient(ctx context.Context, logger zerolog.Logger, ops ...License func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { // License can be provided via environment variable for AWS Marketplace or CLI flag - switch { case lc.isMarketplaceLicense: return lc.validateMarketplaceLicense(ctx) From b8e82bae0b39a142a1dbc138f1c2e59bbe562c7c Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:05:06 -0500 Subject: [PATCH 11/17] Update offline.go --- premium/offline.go | 1 - 1 file changed, 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index fe0f7a355a..1ed180f097 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -112,7 +112,6 @@ func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { default: return ErrLicenseNotApplicable } - } func (lc CQLicenseClient) validateCQLicense() error { From 7bbce8e5c20355dcb5f78f59993a30783b715bff Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:06:12 -0500 Subject: [PATCH 12/17] Update offline.go --- premium/offline.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index 1ed180f097..08025ee3a3 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -108,7 +108,7 @@ func (lc CQLicenseClient) ValidateLicense(ctx context.Context) error { case lc.isMarketplaceLicense: return lc.validateMarketplaceLicense(ctx) case lc.licenseFileOrDirectory != "": - lc.validateCQLicense() + return lc.validateCQLicense() default: return ErrLicenseNotApplicable } From f2d4386e997ebd8dc4bfb67cbb2d37d18d13287e Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:16:36 -0500 Subject: [PATCH 13/17] Update offline.go --- premium/offline.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index 08025ee3a3..899108aa9d 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -48,6 +48,8 @@ var publicKey string var timeFunc = time.Now +const awsProductSKU = "55ukc0d5qv3gebks148tjr62j" + //go:generate mockgen -package=mocks -destination=../premium/mocks/licensemanager.go -source=offline.go AWSLicenseManagerInterface type AWSLicenseManagerInterface interface { CheckoutLicense(ctx context.Context, params *licensemanager.CheckoutLicenseInput, optFns ...func(*licensemanager.Options)) (*licensemanager.CheckoutLicenseOutput, error) @@ -238,7 +240,7 @@ func (lc CQLicenseClient) validateMarketplaceLicense(ctx context.Context) error resp, err := lc.awsLicenseManagerClient.CheckoutLicense(ctx, &licensemanager.CheckoutLicenseInput{ CheckoutType: types.CheckoutTypeProvisional, ClientToken: aws.String(clientToken.String()), - ProductSKU: aws.String("55ukc0d5qv3gebks148tjr62j"), + ProductSKU: aws.String(AWSProductSKU), Entitlements: []types.EntitlementData{ { Name: aws.String("Unlimited"), From f66e4834c1a52689cd4682d48634bbe7c4da6ac8 Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:17:13 -0500 Subject: [PATCH 14/17] Update offline.go --- premium/offline.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index 899108aa9d..81541bdb0a 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -240,7 +240,7 @@ func (lc CQLicenseClient) validateMarketplaceLicense(ctx context.Context) error resp, err := lc.awsLicenseManagerClient.CheckoutLicense(ctx, &licensemanager.CheckoutLicenseInput{ CheckoutType: types.CheckoutTypeProvisional, ClientToken: aws.String(clientToken.String()), - ProductSKU: aws.String(AWSProductSKU), + ProductSKU: aws.String(awsProductSKU), Entitlements: []types.EntitlementData{ { Name: aws.String("Unlimited"), From b0817504f86d68f73f306d25ff1c40d7c8be0603 Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 12:17:50 -0500 Subject: [PATCH 15/17] Update offline_test.go --- premium/offline_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/premium/offline_test.go b/premium/offline_test.go index 0cbb56b37b..ff251dadca 100644 --- a/premium/offline_test.go +++ b/premium/offline_test.go @@ -180,7 +180,7 @@ func TestValidateMarketplaceLicense(t *testing.T) { in := licenseInput{ CheckoutLicenseInput: licensemanager.CheckoutLicenseInput{ CheckoutType: types.CheckoutTypeProvisional, - ProductSKU: aws.String("55ukc0d5qv3gebks148tjr62j"), + ProductSKU: aws.String(awsProductSKU), Entitlements: []types.EntitlementData{ { Name: aws.String("Unlimited"), From 7c4a85ad8b368da1d9b71dfcb75af61e2a70ff8a Mon Sep 17 00:00:00 2001 From: bbernays Date: Wed, 4 Sep 2024 17:25:16 -0500 Subject: [PATCH 16/17] Update offline.go --- premium/offline.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index 81541bdb0a..f879b620a5 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -48,7 +48,7 @@ var publicKey string var timeFunc = time.Now -const awsProductSKU = "55ukc0d5qv3gebks148tjr62j" +const awsProductSKU = "prod-7lvadaavrjurk" //go:generate mockgen -package=mocks -destination=../premium/mocks/licensemanager.go -source=offline.go AWSLicenseManagerInterface type AWSLicenseManagerInterface interface { From 508a633cbc08a7d66da2bc6ac051141b114b5eff Mon Sep 17 00:00:00 2001 From: bbernays Date: Thu, 5 Sep 2024 15:51:59 -0500 Subject: [PATCH 17/17] Update offline.go --- premium/offline.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/premium/offline.go b/premium/offline.go index f879b620a5..b9034be828 100644 --- a/premium/offline.go +++ b/premium/offline.go @@ -48,7 +48,7 @@ var publicKey string var timeFunc = time.Now -const awsProductSKU = "prod-7lvadaavrjurk" +const awsProductSKU = "prod-2trmtbe74klkg" //go:generate mockgen -package=mocks -destination=../premium/mocks/licensemanager.go -source=offline.go AWSLicenseManagerInterface type AWSLicenseManagerInterface interface {