-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OCM-2966 : Feat : Added subscription_type parameter to create cluster command #531
Changes from 3 commits
73e9766
206f64e
7d41647
7881eb9
cbfc5f4
c29ee4d
dd79832
92422d8
1b0df07
1bfbd0f
abe8d9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,17 +33,23 @@ import ( | |
"github.com/openshift-online/ocm-cli/pkg/provider" | ||
"github.com/openshift-online/ocm-cli/pkg/utils" | ||
sdk "github.com/openshift-online/ocm-sdk-go" | ||
amv1 "github.com/openshift-online/ocm-sdk-go/accountsmgmt/v1" | ||
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" | ||
"github.com/openshift/rosa/pkg/interactive" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
) | ||
|
||
var ValidSubscriptionTypes = []string{StandardSubscriptionType, marketplaceRhmSubscriptionType, marketplaceGcpSubscriptionType} | ||
|
||
const ( | ||
defaultIngressRouteSelectorFlag = "default-ingress-route-selector" | ||
defaultIngressExcludedNamespacesFlag = "default-ingress-excluded-namespaces" | ||
defaultIngressWildcardPolicyFlag = "default-ingress-wildcard-policy" | ||
defaultIngressNamespaceOwnershipPolicyFlag = "default-ingress-namespace-ownership-policy" | ||
StandardSubscriptionType = "standard" | ||
marketplaceRhmSubscriptionType = "marketplace-rhm" | ||
marketplaceGcpSubscriptionType = "marketplace-gcp" | ||
) | ||
|
||
var args struct { | ||
|
@@ -68,6 +74,7 @@ var args struct { | |
clusterWideProxy c.ClusterWideProxy | ||
gcpServiceAccountFile arguments.FilePath | ||
etcdEncryption bool | ||
subscriptionType string | ||
|
||
// Scaling options | ||
computeMachineType string | ||
|
@@ -301,6 +308,15 @@ func init() { | |
fmt.Sprintf("Namespace Ownership Policy for ingress. Options are %s", | ||
strings.Join(ingress.ValidNamespaceOwnershipPolicies, ",")), | ||
) | ||
|
||
fs.StringVar( | ||
&args.subscriptionType, | ||
"subscription-type", | ||
StandardSubscriptionType, | ||
fmt.Sprintf("The subscription billing model for the cluster."), | ||
) | ||
arguments.SetQuestion(fs, "subscription-type", "Subscription type:") | ||
Cmd.RegisterFlagCompletionFunc("subscription-type", arguments.MakeCompleteFunc(getSubscriptionTypeOptions)) | ||
} | ||
|
||
func osdProviderOptions(_ *sdk.Connection) ([]arguments.Option, error) { | ||
|
@@ -377,6 +393,56 @@ func getVersionOptionsWithDefault(connection *sdk.Connection, channelGroup strin | |
return | ||
} | ||
|
||
func getSubscriptionTypeOptions(connection *sdk.Connection) ([]arguments.Option, error) { | ||
options := []arguments.Option{} | ||
billingModels, err := getBillingModels(connection) | ||
if err != nil { | ||
return options, err | ||
} | ||
for _, billingModel := range billingModels { | ||
options = append(options, arguments.Option{ | ||
Value: fmt.Sprintf("%s (%s)", billingModel.Id(), billingModel.Description()), | ||
Description: billingModel.Description(), | ||
}) | ||
} | ||
return options, nil | ||
} | ||
|
||
func getSubscriptionTypeIdFromDescription(connection *sdk.Connection, value string) string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest using the same approach used for subnets, see https://github.com/openshift-online/ocm-cli/blob/main/cmd/ocm/create/cluster/cmd.go#L885 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used similar methods as subnets |
||
billingModels, _ := getBillingModels(connection) | ||
for _, billingModel := range billingModels { | ||
if value == fmt.Sprintf("%s (%s)", billingModel.Id(), billingModel.Description()) { | ||
return billingModel.Id() | ||
} | ||
} | ||
return "" | ||
} | ||
|
||
func getBillingModel(connection *sdk.Connection, billingModelID string) (*amv1.BillingModelItem, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can make this function reusable (as well as getBillingModels) by moving them to its own package under pkg/billing, for example. This logic doesn't really belong to cmd/ocm/create/cluster/cmd.go There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to the billing package |
||
bilingModel, err := connection.AccountsMgmt().V1().BillingModels().BillingModel(billingModelID).Get().Send() | ||
if err != nil { | ||
return nil, err | ||
} | ||
return bilingModel.Body(), nil | ||
} | ||
|
||
func getBillingModels(connection *sdk.Connection) ([]*amv1.BillingModelItem, error) { | ||
response, err := connection.AccountsMgmt().V1().BillingModels().List().Send() | ||
if err != nil { | ||
return nil, err | ||
} | ||
billingModels := response.Items().Slice() | ||
var validBillingModel []*amv1.BillingModelItem | ||
for _, billingModel := range billingModels { | ||
for _, validSubscriptionTypeId := range ValidSubscriptionTypes { | ||
if billingModel.Id() == validSubscriptionTypeId { | ||
validBillingModel = append(validBillingModel, billingModel) | ||
} | ||
} | ||
} | ||
return validBillingModel, nil | ||
} | ||
|
||
func getMachineTypeOptions(connection *sdk.Connection) ([]arguments.Option, error) { | ||
return provider.GetMachineTypeOptions( | ||
connection.ClustersMgmt().V1(), | ||
|
@@ -421,9 +487,27 @@ func preRun(cmd *cobra.Command, argv []string) error { | |
// Validate flags / ask for missing data. | ||
fs := cmd.Flags() | ||
|
||
// Get options for subscription type | ||
subscriptionTypeOptions, _ := getSubscriptionTypeOptions(connection) | ||
err = arguments.PromptOneOf(fs, "subscription-type", subscriptionTypeOptions) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Only offer the 2 providers known to support OSD now; | ||
// but don't validate if set, to not block `ocm` CLI from creating clusters on future providers. | ||
providers, _ := osdProviderOptions(connection) | ||
|
||
// If marketplace-gcp subscription type is used, provider can only be GCP | ||
gcpBillingModel, _ := getBillingModel(connection, marketplaceGcpSubscriptionType) | ||
isGcpSubscriptionType := args.subscriptionType == fmt.Sprintf("%s (%s)", gcpBillingModel.Id(), gcpBillingModel.Description()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed |
||
if isGcpSubscriptionType { | ||
providers = []arguments.Option{ | ||
{Value: c.ProviderGCP, Description: ""}, | ||
} | ||
args.ccs.Enabled = true | ||
} | ||
|
||
err = arguments.PromptOneOf(fs, "provider", providers) | ||
if err != nil { | ||
return err | ||
|
@@ -435,7 +519,7 @@ func preRun(cmd *cobra.Command, argv []string) error { | |
args.clusterWideProxy.Enabled = true | ||
} | ||
|
||
err = promptCCS(fs) | ||
err = promptCCS(fs, isGcpSubscriptionType) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -530,6 +614,7 @@ func preRun(cmd *cobra.Command, argv []string) error { | |
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -554,6 +639,10 @@ func run(cmd *cobra.Command, argv []string) error { | |
return err | ||
} | ||
|
||
if args.interactive { | ||
args.subscriptionType = getSubscriptionTypeIdFromDescription(connection, args.subscriptionType) | ||
} | ||
|
||
clusterConfig := c.Spec{ | ||
Name: args.clusterName, | ||
Region: args.region, | ||
|
@@ -577,6 +666,7 @@ func run(cmd *cobra.Command, argv []string) error { | |
Private: &args.private, | ||
EtcdEncryption: args.etcdEncryption, | ||
DefaultIngress: defaultIngress, | ||
SubscriptionType: args.subscriptionType, | ||
} | ||
|
||
cluster, err := c.CreateCluster(connection.ClustersMgmt().V1(), clusterConfig, args.dryRun) | ||
|
@@ -1036,8 +1126,12 @@ func promptExistingVPC(fs *pflag.FlagSet, connection *sdk.Connection) error { | |
return err | ||
} | ||
|
||
func promptCCS(fs *pflag.FlagSet) error { | ||
err := arguments.PromptBool(fs, "ccs") | ||
func promptCCS(fs *pflag.FlagSet, isGcpSubscriptionType bool) error { | ||
var err error | ||
// If marketplace-gcp subscription type is used, ccs should by default be true | ||
if !isGcpSubscriptionType { | ||
err = arguments.PromptBool(fs, "ccs") | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ require ( | |
github.com/nwidger/jsoncolor v0.3.2 | ||
github.com/onsi/ginkgo/v2 v2.11.0 | ||
github.com/onsi/gomega v1.27.8 | ||
github.com/openshift-online/ocm-sdk-go v0.1.356 | ||
github.com/openshift-online/ocm-sdk-go v0.1.367 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We will need to wait the next version as we are changing the BillingModelItem from a struct to a class. See https://github.com/openshift-online/ocm-api-model/pull/831/files There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used latest sdk version |
||
github.com/openshift/rosa v1.2.24 | ||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 | ||
github.com/spf13/cobra v1.7.0 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,7 @@ import ( | |
"time" | ||
|
||
sdk "github.com/openshift-online/ocm-sdk-go" | ||
amsv1 "github.com/openshift-online/ocm-sdk-go/accountsmgmt/v1" | ||
amv1 "github.com/openshift-online/ocm-sdk-go/accountsmgmt/v1" | ||
This comment was marked as resolved.
Sorry, something went wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed these to keep is consistent with CS (they have used cmv1 instead of cmsv1), but we can revert this back |
||
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" | ||
) | ||
|
||
|
@@ -68,6 +68,7 @@ type Spec struct { | |
ChannelGroup string | ||
Expiration time.Time | ||
EtcdEncryption bool | ||
SubscriptionType string | ||
|
||
// Scaling config | ||
ComputeMachineType string | ||
|
@@ -312,6 +313,7 @@ func CreateCluster(cmv1Client *cmv1.Client, config Spec, dryRun bool) (*cmv1.Clu | |
ID(config.Flavour), | ||
). | ||
EtcdEncryption(config.EtcdEncryption). | ||
BillingModel(cmv1.BillingModel(config.SubscriptionType)). | ||
Properties(clusterProperties) | ||
|
||
clusterBuilder = clusterBuilder.Version( | ||
|
@@ -703,7 +705,7 @@ func GetClusterAddOns(connection *sdk.Connection, clusterID string) ([]*AddOnIte | |
} | ||
|
||
// Only display add-ons for which the org has quota | ||
quotaCosts.Each(func(quotaCost *amsv1.QuotaCost) bool { | ||
quotaCosts.Each(func(quotaCost *amv1.QuotaCost) bool { | ||
relatedResources := quotaCost.RelatedResources() | ||
for _, relatedResource := range relatedResources { | ||
if relatedResource.ResourceType() == "add-on" && | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to add the description to the value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added it before since interactive mode has a ? option to show description, but seems it only shows descriptions of the argument, not the drop down. Removed the description