44 "context"
55 "encoding/json"
66 "fmt"
7- "strings"
87
98 "github.com/goccy/go-yaml"
109 "github.com/spf13/cobra"
@@ -15,128 +14,101 @@ import (
1514 "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
1615 "github.com/stackitcloud/stackit-cli/internal/pkg/print"
1716 "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client"
17+ "github.com/stackitcloud/stackit-cli/internal/pkg/utils"
1818 "github.com/stackitcloud/stackit-sdk-go/services/iaas"
1919)
2020
21+ const (
22+ nameFlag = "name"
23+ descriptionFlag = "description"
24+ statefulFlag = "stateful"
25+ labelsFlag = "labels"
26+ )
27+
2128type inputModel struct {
2229 * globalflags.GlobalFlagModel
23- Labels map [string ]any
24- Description string
25- Name string
26- Stateful bool
30+ Labels * map [string ]string
31+ Description * string
32+ Name * string
33+ Stateful * bool
2734}
2835
2936func NewCmd (p * print.Printer ) * cobra.Command {
3037 cmd := & cobra.Command {
3138 Use : "create" ,
32- Short : "create security groups" ,
33- Long : "create security groups" ,
39+ Short : "Creates security groups" ,
40+ Long : "Creates security groups. " ,
3441 Args : args .NoArgs ,
3542 Example : examples .Build (
36- examples .NewExample (`create a named group` , `$ stackit beta security-group create --name my-new-group` ),
37- examples .NewExample (`create a named group with labels` , `$ stackit beta security-group create --name my-new-group --labels label1=value1,label2=value2` ),
43+ examples .NewExample (`Create a named group` , `$ stackit beta security-group create --name my-new-group` ),
44+ examples .NewExample (`Create a named group with labels` , `$ stackit beta security-group create --name my-new-group --labels label1=value1,label2=value2` ),
3845 ),
39- RunE : func (cmd * cobra.Command , args []string ) error {
40- return executeCreate (cmd , p , args )
41- },
42- }
46+ RunE : func (cmd * cobra.Command , _ []string ) error {
47+ ctx := context .Background ()
48+ model , err := parseInput (p , cmd )
49+ if err != nil {
50+ return err
51+ }
4352
44- configureFlags (cmd )
45- return cmd
46- }
53+ // Configure API client
54+ apiClient , err := client .ConfigureClient (p )
55+ if err != nil {
56+ return err
57+ }
4758
48- func configureFlags (cmd * cobra.Command ) {
49- cmd .Flags ().String ("name" , "" , "the name of the security group. Must be <= 63 chars" )
50- cmd .Flags ().String ("description" , "" , "an optional description of the security group. Must be <= 127 chars" )
51- cmd .Flags ().Bool ("stateful" , false , "create a stateful or a stateless security group" )
52- cmd .Flags ().StringSlice ("labels" , nil , "a list of labels in the form <key>=<value>" )
59+ if ! model .AssumeYes {
60+ prompt := fmt .Sprintf ("Are you sure you want to create the security group %q?" , * model .Name )
61+ err = p .PromptForConfirmation (prompt )
62+ if err != nil {
63+ return err
64+ }
65+ }
5366
54- if err := flags .MarkFlagsRequired (cmd , "name" ); err != nil {
55- cobra .CheckErr (err )
56- }
57- }
67+ // Call API
68+ request := buildRequest (ctx , model , apiClient )
5869
59- func executeCreate (cmd * cobra.Command , p * print.Printer , _ []string ) error {
60- p .Info ("executing create command" )
61- ctx := context .Background ()
62- model , err := parseInput (p , cmd )
63- if err != nil {
64- return err
65- }
70+ group , err := request .Execute ()
71+ if err != nil {
72+ return fmt .Errorf ("create security group: %w" , err )
73+ }
6674
67- // Configure API client
68- apiClient , err := client .ConfigureClient (p )
69- if err != nil {
70- return err
71- }
75+ if err := outputResult (p , model , group ); err != nil {
76+ return err
77+ }
7278
73- if ! model .AssumeYes {
74- prompt := fmt .Sprintf ("Are you sure you want to create the security group %q?" , model .Name )
75- err = p .PromptForConfirmation (prompt )
76- if err != nil {
77- return err
78- }
79+ return nil
80+ },
7981 }
8082
81- // Call API
82- request := buildRequest (ctx , model , apiClient )
83+ configureFlags (cmd )
84+ return cmd
85+ }
8386
84- operationState := "Enabled"
85- if model . Async {
86- operationState = "Triggered security group creation"
87- }
88- p . Info ( "%s security group %q for %q \n " , operationState , model . Name , model . ProjectId )
87+ func configureFlags ( cmd * cobra. Command ) {
88+ cmd . Flags (). String ( nameFlag , "" , "The name of the security group." )
89+ cmd . Flags (). String ( descriptionFlag , "" , "An optional description of the security group." )
90+ cmd . Flags (). Bool ( statefulFlag , false , "Create a stateful or a stateless security group" )
91+ cmd . Flags (). StringToString ( labelsFlag , nil , "Labels are key-value string pairs which can be attached to a network-interface. E.g. '--labels key1=value1,key2=value2,...'" )
8992
90- group , err := request .Execute ()
91- if err != nil {
92- return fmt .Errorf ("create security group: %w" , err )
93- }
94- if err := outputResult (p , model , group );err != nil {
95- return err
93+ if err := flags .MarkFlagsRequired (cmd , nameFlag ); err != nil {
94+ cobra .CheckErr (err )
9695 }
97-
98- return nil
9996}
10097
10198func parseInput (p * print.Printer , cmd * cobra.Command ) (* inputModel , error ) {
10299 globalFlags := globalflags .Parse (p , cmd )
103100 if globalFlags .ProjectId == "" {
104101 return nil , & errors.ProjectIdError {}
105102 }
106- name := flags .FlagToStringValue (p , cmd , "name" )
107- if len (name ) >= 64 {
108- return nil , & errors.ArgValidationError {
109- Arg : "invalid name" ,
110- Details : "name exceeds 63 characters in length" ,
111- }
112- }
103+ name := flags .FlagToStringValue (p , cmd , nameFlag )
113104
114- labels := make (map [string ]any )
115- for _ , label := range flags .FlagToStringSliceValue (p , cmd , "labels" ) {
116- parts := strings .Split (label , "=" )
117- if len (parts ) != 2 {
118- return nil , & errors.ArgValidationError {
119- Arg : "labels" ,
120- Details : "invalid label declaration. Must be in the form <key>=<value>" ,
121- }
122- }
123- labels [parts [0 ]] = parts [1 ]
124-
125- }
126- description := flags .FlagToStringValue (p , cmd , "description" )
127- if len (description ) >= 128 {
128- return nil , & errors.ArgValidationError {
129- Arg : "invalid description" ,
130- Details : "description exceeds 127 characters in length" ,
131- }
132- }
133105 model := inputModel {
134106 GlobalFlagModel : globalFlags ,
135- Name : name ,
107+ Name : & name ,
136108
137- Labels : labels ,
138- Description : description ,
139- Stateful : flags .FlagToBoolValue (p , cmd , "stateful" ),
109+ Labels : flags . FlagToStringToStringPointer ( p , cmd , labelsFlag ) ,
110+ Description : flags . FlagToStringPointer ( p , cmd , descriptionFlag ) ,
111+ Stateful : flags .FlagToBoolPointer (p , cmd , statefulFlag ),
140112 }
141113
142114 if p .IsVerbosityDebug () {
@@ -153,19 +125,23 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) {
153125
154126func buildRequest (ctx context.Context , model * inputModel , apiClient * iaas.APIClient ) iaas.ApiCreateSecurityGroupRequest {
155127 request := apiClient .CreateSecurityGroup (ctx , model .ProjectId )
156- payload := iaas .NewCreateSecurityGroupPayload (& model .Name )
157- payload .Description = & model .Description
158- if model .Labels != nil {
159- // this check assure that we don't end up with a pointer to nil
160- // which is a thing in go!
161- payload .Labels = & model .Labels
162- }
163- payload .Name = & model .Name
164- payload .Stateful = & model .Stateful
165- request = request .CreateSecurityGroupPayload (* payload )
166128
167- return request
129+ var labelsMap * map [string ]any
130+ if model .Labels != nil && len (* model .Labels ) > 0 {
131+ // convert map[string]string to map[string]interface{}
132+ labelsMap = utils .Ptr (map [string ]interface {}{})
133+ for k , v := range * model .Labels {
134+ (* labelsMap )[k ] = v
135+ }
136+ }
137+ payload := iaas.CreateSecurityGroupPayload {
138+ Description : model .Description ,
139+ Labels : labelsMap ,
140+ Name : model .Name ,
141+ Stateful : model .Stateful ,
142+ }
168143
144+ return request .CreateSecurityGroupPayload (payload )
169145}
170146
171147func outputResult (p * print.Printer , model * inputModel , resp * iaas.SecurityGroup ) error {
@@ -187,11 +163,7 @@ func outputResult(p *print.Printer, model *inputModel, resp *iaas.SecurityGroup)
187163
188164 return nil
189165 default :
190- operationState := "Created"
191- if model .Async {
192- operationState = "Triggered creation of"
193- }
194- p .Outputf ("%s security group %q\n " , operationState , model .Name )
166+ p .Outputf ("Created security group %q\n " , * model .Name )
195167 return nil
196168 }
197169}
0 commit comments