Skip to content

Commit a2e1b6a

Browse files
feat(kafka create): enable creating long-lived trial instances (#1809)
* feat(kafka create): enable creating long-lived trial instances (#1800) * feat(kafka): add promote command (#1805)
1 parent 09f89da commit a2e1b6a

File tree

74 files changed

+3604
-192
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+3604
-192
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
github.com/redhat-developer/app-services-sdk-go/accountmgmt v0.3.0
2626
github.com/redhat-developer/app-services-sdk-go/connectormgmt v0.10.0
2727
github.com/redhat-developer/app-services-sdk-go/kafkainstance v0.11.0
28-
github.com/redhat-developer/app-services-sdk-go/kafkamgmt v0.15.0
28+
github.com/redhat-developer/app-services-sdk-go/kafkamgmt v0.19.0
2929
github.com/redhat-developer/app-services-sdk-go/registryinstance v0.8.2
3030
github.com/redhat-developer/app-services-sdk-go/registrymgmt v0.11.1
3131
github.com/redhat-developer/app-services-sdk-go/serviceaccountmgmt v0.9.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,8 @@ github.com/redhat-developer/app-services-sdk-go/connectormgmt v0.10.0 h1:CURbTHI
700700
github.com/redhat-developer/app-services-sdk-go/connectormgmt v0.10.0/go.mod h1:t3IV0eKUPgCQjoInv2l8B/NMm2OVemCxGFO/z91wsCU=
701701
github.com/redhat-developer/app-services-sdk-go/kafkainstance v0.11.0 h1:WdwVjneugUC898RSHuc2vLwlcNgPh3oF7/fuxEEGGPg=
702702
github.com/redhat-developer/app-services-sdk-go/kafkainstance v0.11.0/go.mod h1:yazwUm4IHuIWrQ0CCsqN0h7rHZx51nlFbYWKnUn7B84=
703-
github.com/redhat-developer/app-services-sdk-go/kafkamgmt v0.15.0 h1:0kNYXkZHEtoAfXJuydT5LgDjulP/3ePWI626lPfDSm0=
704-
github.com/redhat-developer/app-services-sdk-go/kafkamgmt v0.15.0/go.mod h1:ILvcakLEXMLZyRdO//WJZNk9fdFbnU+cM3XrBvubE64=
703+
github.com/redhat-developer/app-services-sdk-go/kafkamgmt v0.19.0 h1:RVDEeUfBgMzAK+BCnlhfHGHp2YYW6GH6jgYOv2jwYVY=
704+
github.com/redhat-developer/app-services-sdk-go/kafkamgmt v0.19.0/go.mod h1:ILvcakLEXMLZyRdO//WJZNk9fdFbnU+cM3XrBvubE64=
705705
github.com/redhat-developer/app-services-sdk-go/registryinstance v0.8.2 h1:U2je87d/DIeOaQIycg2Y7TLiESmGu0/0rQC5n64Od0Y=
706706
github.com/redhat-developer/app-services-sdk-go/registryinstance v0.8.2/go.mod h1:HkNzOWHTW/SomobQ4343+yR4oTmiyvm85BIWlsh0qbA=
707707
github.com/redhat-developer/app-services-sdk-go/registrymgmt v0.11.1 h1:VOv3wcodQ6EpKp2RRntMMTMuQSnNv1sqLezdbv18mjs=

pkg/cmd/kafka/create/api_validators.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type ValidatorInput struct {
2626
conn connection.Connection
2727
}
2828

29-
var validBillingModels []string = []string{accountmgmtutil.QuotaMarketplaceType, accountmgmtutil.QuotaStandardType}
29+
var validBillingModels []string = []string{accountmgmtutil.QuotaMarketplaceType, accountmgmtutil.QuotaStandardType, accountmgmtutil.QuotaEvalType}
3030

3131
func (input *ValidatorInput) ValidateProviderAndRegion() error {
3232
f := input.f

pkg/cmd/kafka/create/create.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ func NewCreateCommand(f *factory.Factory) *cobra.Command {
110110
return f.Localizer.MustLocalizeError("kafka.create.error.standard.invalidFlags")
111111
}
112112

113+
if opts.billingModel == accountmgmtutil.QuotaEvalType && (opts.marketplaceAcctId != "" || opts.marketplace != "") {
114+
return f.Localizer.MustLocalizeError("kafka.create.error.eval.invalidFlags")
115+
}
116+
113117
if !f.IOStreams.CanPrompt() && opts.name == "" {
114118
return f.Localizer.MustLocalizeError("kafka.create.argument.name.error.requiredWhenNonInteractive")
115119
} else if opts.name == "" {
@@ -135,13 +139,13 @@ func NewCreateCommand(f *factory.Factory) *cobra.Command {
135139
flags.StringVar(&opts.provider, FlagProvider, "", f.Localizer.MustLocalize("kafka.create.flag.cloudProvider.description"))
136140
flags.StringVar(&opts.region, FlagRegion, "", f.Localizer.MustLocalize("kafka.create.flag.cloudRegion.description"))
137141
flags.StringVar(&opts.size, FlagSize, "", f.Localizer.MustLocalize("kafka.create.flag.size.description"))
138-
flags.StringVar(&opts.marketplaceAcctId, FlagMarketPlaceAcctID, "", f.Localizer.MustLocalize("kafka.create.flag.marketplaceId.description"))
139-
flags.StringVar(&opts.marketplace, FlagMarketPlace, "", f.Localizer.MustLocalize("kafka.create.flag.marketplaceType.description"))
142+
flags.StringVar(&opts.marketplaceAcctId, FlagMarketPlaceAcctID, "", f.Localizer.MustLocalize("kafka.common.flag.marketplaceId.description"))
143+
flags.StringVar(&opts.marketplace, FlagMarketPlace, "", f.Localizer.MustLocalize("kafka.common.flag.marketplaceType.description"))
140144
flags.AddOutput(&opts.outputFormat)
141145
flags.BoolVar(&opts.autoUse, "use", true, f.Localizer.MustLocalize("kafka.create.flag.autoUse.description"))
142146
flags.BoolVarP(&opts.wait, "wait", "w", false, f.Localizer.MustLocalize("kafka.create.flag.wait.description"))
143147
flags.BoolVarP(&opts.dryRun, "dry-run", "", false, f.Localizer.MustLocalize("kafka.create.flag.dryrun.description"))
144-
flags.StringVar(&opts.billingModel, FlagBillingModel, "", f.Localizer.MustLocalize("kafka.create.flag.billingModel.description"))
148+
flags.StringVar(&opts.billingModel, FlagBillingModel, "", f.Localizer.MustLocalize("kafka.common.flag.billingModel.description"))
145149
flags.AddBypassTermsCheck(&opts.bypassChecks)
146150

147151
_ = cmd.RegisterFlagCompletionFunc(FlagProvider, func(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {

pkg/cmd/kafka/create/data.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func mapAmsTypeToBackendType(amsType *accountmgmtutil.QuotaSpec) CloudProviderId
2727
switch amsType.Name {
2828
case accountmgmtutil.QuotaStandardType:
2929
return StandardType
30+
case accountmgmtutil.QuotaEvalType:
31+
return StandardType
3032
case accountmgmtutil.QuotaMarketplaceType:
3133
return StandardType
3234
case accountmgmtutil.QuotaTrialType:
@@ -63,6 +65,10 @@ func FetchSupportedBillingModels(userQuotas *accountmgmtutil.OrgQuotas, provider
6365
billingModels = append(billingModels, accountmgmtutil.QuotaStandardType)
6466
}
6567

68+
if len(userQuotas.EvalQuotas) > 0 {
69+
billingModels = append(billingModels, accountmgmtutil.QuotaEvalType)
70+
}
71+
6672
if len(userQuotas.MarketplaceQuotas) > 0 {
6773
if provider != "" {
6874
for _, quota := range userQuotas.MarketplaceQuotas {

pkg/cmd/kafka/kafka.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/delete"
1212
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/describe"
1313
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/list"
14+
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/promote"
1415
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/providers"
1516
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/topic"
1617
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/update"
@@ -42,6 +43,7 @@ func NewKafkaCommand(f *factory.Factory) *cobra.Command {
4243
acl.NewAclCommand(f),
4344
billing.NewBillingCommand(f),
4445
providers.NewProviderCommand(f),
46+
promote.NewPromoteCommand(f),
4547
)
4648

4749
return cmd

pkg/cmd/kafka/promote/promote.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package promote
2+
3+
import (
4+
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/flagutil"
5+
"github.com/redhat-developer/app-services-cli/pkg/core/localize"
6+
"github.com/redhat-developer/app-services-cli/pkg/shared/contextutil"
7+
"github.com/redhat-developer/app-services-cli/pkg/shared/factory"
8+
"github.com/redhat-developer/app-services-cli/pkg/shared/kafkautil"
9+
"github.com/spf13/cobra"
10+
11+
kafkamgmtclient "github.com/redhat-developer/app-services-sdk-go/kafkamgmt/apiv1/client"
12+
kafkamgmtv1errors "github.com/redhat-developer/app-services-sdk-go/kafkamgmt/apiv1/error"
13+
)
14+
15+
type options struct {
16+
id string
17+
name string
18+
marketplaceAcctId string
19+
marketplace string
20+
desiredBillingModel string
21+
22+
f *factory.Factory
23+
}
24+
25+
func NewPromoteCommand(f *factory.Factory) *cobra.Command {
26+
27+
opts := &options{
28+
f: f,
29+
}
30+
31+
cmd := &cobra.Command{
32+
Use: "promote",
33+
Short: opts.f.Localizer.MustLocalize("kafka.promote.cmd.shortDescription"),
34+
Long: opts.f.Localizer.MustLocalize("kafka.promote.cmd.longDescription"),
35+
Example: opts.f.Localizer.MustLocalize("kafka.promote.cmd.example"),
36+
Args: cobra.NoArgs,
37+
Hidden: true,
38+
RunE: func(cmd *cobra.Command, args []string) error {
39+
40+
if opts.name != "" && opts.id != "" {
41+
return opts.f.Localizer.MustLocalizeError("service.error.idAndNameCannotBeUsed")
42+
}
43+
44+
if opts.id != "" || opts.name != "" {
45+
return runPromote(opts)
46+
}
47+
48+
kafkaInstance, err := contextutil.GetCurrentKafkaInstance(f)
49+
if err != nil {
50+
return err
51+
}
52+
53+
opts.id = kafkaInstance.GetId()
54+
55+
return runPromote(opts)
56+
},
57+
}
58+
59+
flags := flagutil.NewFlagSet(cmd, opts.f.Localizer)
60+
61+
flags.StringVar(&opts.id, "id", "", opts.f.Localizer.MustLocalize("kafka.promote.flag.id"))
62+
flags.StringVar(&opts.name, "name", "", opts.f.Localizer.MustLocalize("kafka.promote.flag.name"))
63+
64+
flags.StringVar(&opts.marketplaceAcctId, "marketplace-account-id", "", f.Localizer.MustLocalize("kafka.common.flag.marketplaceId.description"))
65+
flags.StringVar(&opts.marketplace, "marketplace", "", f.Localizer.MustLocalize("kafka.common.flag.marketplaceType.description"))
66+
flags.StringVar(&opts.desiredBillingModel, "billing-model", "", f.Localizer.MustLocalize("kafka.common.flag.billingModel.description"))
67+
68+
_ = cmd.MarkFlagRequired("billing-model")
69+
70+
return cmd
71+
72+
}
73+
74+
func runPromote(opts *options) error {
75+
76+
conn, err := opts.f.Connection()
77+
if err != nil {
78+
return err
79+
}
80+
81+
api := conn.API()
82+
83+
if opts.name != "" {
84+
response, _, newErr := kafkautil.GetKafkaByName(opts.f.Context, api.KafkaMgmt(), opts.name)
85+
if newErr != nil {
86+
return newErr
87+
}
88+
89+
opts.id = response.GetId()
90+
}
91+
92+
a := api.KafkaMgmt().PromoteKafka(opts.f.Context, opts.id)
93+
94+
var promoteOptions kafkamgmtclient.KafkaPromoteRequest
95+
96+
promoteOptions.SetDesiredKafkaBillingModel(opts.desiredBillingModel)
97+
98+
if opts.marketplace != "" {
99+
promoteOptions.SetDesiredMarketplace(opts.marketplace)
100+
}
101+
102+
if opts.marketplaceAcctId != "" {
103+
promoteOptions.SetDesiredKafkaBillingModel(opts.marketplaceAcctId)
104+
}
105+
106+
a = a.KafkaPromoteRequest(promoteOptions)
107+
a = a.Async(true)
108+
109+
httpRes, err := a.Execute()
110+
if httpRes != nil {
111+
defer httpRes.Body.Close()
112+
}
113+
114+
if apiErr := kafkamgmtv1errors.GetAPIError(err); apiErr != nil {
115+
switch apiErr.GetCode() {
116+
case kafkamgmtv1errors.ERROR_120:
117+
// For standard instances
118+
return opts.f.Localizer.MustLocalizeError("kafka.create.error.quota.exceeded")
119+
case kafkamgmtv1errors.ERROR_24:
120+
// For dev instances
121+
return opts.f.Localizer.MustLocalizeError("kafka.create.error.instance.limit")
122+
case kafkamgmtv1errors.ERROR_9:
123+
return opts.f.Localizer.MustLocalizeError("kafka.create.error.standard.promote")
124+
case kafkamgmtv1errors.ERROR_43:
125+
return opts.f.Localizer.MustLocalizeError("kafka.create.error.billing.invalid", localize.NewEntry("Billing", opts.marketplaceAcctId))
126+
}
127+
}
128+
129+
if err != nil {
130+
return err
131+
}
132+
133+
opts.f.Logger.Info(opts.f.Localizer.MustLocalize("kafka.promote.info.successAsync"))
134+
135+
return nil
136+
}

pkg/core/localize/locales/en/cmd/kafka.en.toml

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ one = 'Kafka instance ID. Uses the current instance if not set'
5454
[kafkas.common.flag.output.description]
5555
one = 'Format in which to display the Kafka instances (choose from: "json", "yml", "yaml")'
5656

57+
[kafka.common.flag.marketplaceId.description]
58+
one = 'Cloud Account ID for the marketplace'
59+
60+
[kafka.common.flag.billingModel.description]
61+
one = 'Billing model to be used'
62+
63+
[kafka.common.flag.marketplaceType.description]
64+
one = 'Name of the marketplace where the instance is purchased on'
65+
5766
[kafka.common.input.instanceName.message]
5867
one = 'Select Kafka instance:'
5968

@@ -286,15 +295,6 @@ one = 'Wait until the Kafka instance is created'
286295
[kafka.create.flag.dryrun.description]
287296
one = 'Validate all user provided arguments without creating the Kafka instance'
288297

289-
[kafka.create.flag.marketplaceId.description]
290-
one = 'Cloud Account ID for the marketplace'
291-
292-
[kafka.create.flag.billingModel.description]
293-
one = 'Billing model to be used'
294-
295-
[kafka.create.flag.marketplaceType.description]
296-
one = 'Name of the marketplace where the instance is purchased on'
297-
298298
[kafka.create.log.info.creatingKafka]
299299
description = 'Message when Kafka instance is being created'
300300
one = 'Creating Kafka instance "{{.Name}}"...'
@@ -370,7 +370,10 @@ one = '"--billing-model", "--marketplace", "--marketplace-account-id" flags are
370370
one = '"--marketplace" and "--marketplace-account-id" flags should be supplied together'
371371

372372
[kafka.create.error.standard.invalidFlags]
373-
one = 'billing model cannot be standard if "--marketplace-account-id" or "--marketplace" are set'
373+
one = 'billing model can not be standard if "--marketplace-account-id" or "--marketplace" are set'
374+
375+
[kafka.create.error.eval.invalidFlags]
376+
one = 'billing model can not be eval if "--marketplace-account-id" or "--marketplace" are set'
374377

375378
[kafka.create.error.conflictError]
376379
one = 'Kafka instance "{{.Name}}" already exists'
@@ -393,6 +396,9 @@ one = 'unable to create new Kafka instance at this time in specified cloud provi
393396
[kafka.create.error.instance.limit]
394397
one = 'maximum number of allowed kafka instances has been reached. Please review all instances that your user has access to and delete one or more instances before creating a new one'
395398

399+
[kafka.create.error.standard.promote]
400+
one = 'only Kafka instances with billing model "eval" can be promoted'
401+
396402
[kafka.create.region.error.invalidRegion]
397403
one = '''
398404
the region "{{.Region}}" is not available for the cloud provider "{{.Provider}}".
@@ -437,6 +443,9 @@ one = "only trial quotas are available, don't specify billing model details"
437443
[kafka.create.quota.error.noMarketplace]
438444
one = "no marketplace quotas are available"
439445

446+
[kafka.create.quota.error.noEval]
447+
one = "no evaluation quotas are available"
448+
440449
[kafka.create.quota.error.noStandard]
441450
one = "no standard quotas are available"
442451

@@ -585,6 +594,26 @@ $ rhoas kafka billing
585594
[kafka.billing.log.info.noStandardInstancesAvailable]
586595
one = "Only developer instances are available"
587596

597+
[kafka.promote.cmd.shortDescription]
598+
one = 'Promote eval Kafka instance'
599+
600+
[kafka.promote.cmd.longDescription]
601+
one = 'Promote an evaluation Kafka instance to billing model "standard" or "marketplace"'
602+
603+
[kafka.promote.cmd.example]
604+
one = '''
605+
# Promote eval instance to standard
606+
$ rhoas kafka promote --billing-model standard --id 1iSY6RQ3JKI8Q0OTmjQFd3ocFRg
607+
'''
608+
609+
[kafka.promote.flag.id]
610+
one = 'ID of the Kafka instance'
611+
612+
[kafka.promote.flag.name]
613+
one = 'Name of the Kafka instance'
614+
615+
[kafka.promote.info.successAsync]
616+
one = 'Kafka instance is being promoted. To monitor its status run "rhoas kafka describe".'
588617

589618
[kafka.list.cmd.shortDescription]
590619
description = "Short description for command"

0 commit comments

Comments
 (0)