@@ -19,32 +19,60 @@ import (
1919)
2020
2121const (
22- flavorsFlag = "flavors"
23- versionsFlag = "versions"
24- storagesFlag = "storages"
25- flavorIdFlag = "flavor-id"
22+ flavorsFlag = "flavors"
23+ versionsFlag = "versions"
24+ storagesFlag = "storages"
25+ userRolesFlag = "user-roles"
26+ dbCollationsFlag = "db-collations"
27+ dbCompatibilitiesFlag = "db-compatibilities"
28+
29+ flavorIdFlag = "flavor-id"
30+ instanceIdFlag = "instance-id"
2631)
2732
2833type inputModel struct {
2934 * globalflags.GlobalFlagModel
3035
31- Flavors bool
32- Versions bool
33- Storages bool
34- FlavorId * string
36+ Flavors bool
37+ Versions bool
38+ Storages bool
39+ UserRoles bool
40+ DBCollations bool
41+ DBCompatibilities bool
42+
43+ FlavorId * string
44+ InstanceId * string
3545}
3646
3747type options struct {
38- Flavors * []sqlserverflex.InstanceFlavorEntry `json:"flavors,omitempty"`
39- Versions * []string `json:"versions,omitempty"`
40- Storages * flavorStorages `json:"flavorStorages,omitempty"`
48+ Flavors * []sqlserverflex.InstanceFlavorEntry `json:"flavors,omitempty"`
49+ Versions * []string `json:"versions,omitempty"`
50+ Storages * flavorStorages `json:"flavorStorages,omitempty"`
51+ UserRoles * instanceUserRoles `json:"userRoles,omitempty"`
52+ DBCollations * instanceDBCollations `json:"dbCollations,omitempty"`
53+ DBCompatibilities * instanceDBCompatibilities `json:"dbCompatibilities,omitempty"`
4154}
4255
4356type flavorStorages struct {
4457 FlavorId string `json:"flavorId"`
4558 Storages * sqlserverflex.ListStoragesResponse `json:"storages"`
4659}
4760
61+ type instanceUserRoles struct {
62+ InstanceId string `json:"instanceId"`
63+ UserRoles []string `json:"userRoles"`
64+ }
65+
66+ type instanceDBCollations struct {
67+ InstanceId string `json:"instanceId"`
68+ DBCollations []sqlserverflex.MssqlDatabaseCollation `json:"dbCollations"`
69+ }
70+
71+ type instanceDBCompatibilities struct {
72+ InstanceId string `json:"instanceId"`
73+ DBCompatibilities []sqlserverflex.MssqlDatabaseCompatibility `json:"dbCompatibilities"`
74+ }
75+
4876func NewCmd (p * print.Printer ) * cobra.Command {
4977 cmd := & cobra.Command {
5078 Use : "options" ,
@@ -92,17 +120,27 @@ func configureFlags(cmd *cobra.Command) {
92120 cmd .Flags ().Bool (flavorsFlag , false , "Lists supported flavors" )
93121 cmd .Flags ().Bool (versionsFlag , false , "Lists supported versions" )
94122 cmd .Flags ().Bool (storagesFlag , false , "Lists supported storages for a given flavor" )
123+ cmd .Flags ().Bool (userRolesFlag , false , "Lists supported user roles for a given instance" )
124+ cmd .Flags ().Bool (dbCollationsFlag , false , "Lists supported database collations for a given instance" )
125+ cmd .Flags ().Bool (dbCompatibilitiesFlag , false , "Lists supported database compatibilities for a given instance" )
95126 cmd .Flags ().String (flavorIdFlag , "" , `The flavor ID to show storages for. Only relevant when "--storages" is passed` )
127+ cmd .Flags ().String (instanceIdFlag , "" , `The instance ID to show user roles, database collations and database compatibilities for. Only relevant when "--user-roles", "--db-collations" or "--db-compatibilities" is passed` )
96128}
97129
98130func parseInput (p * print.Printer , cmd * cobra.Command ) (* inputModel , error ) {
99131 globalFlags := globalflags .Parse (p , cmd )
132+
100133 flavors := flags .FlagToBoolValue (p , cmd , flavorsFlag )
101134 versions := flags .FlagToBoolValue (p , cmd , versionsFlag )
102135 storages := flags .FlagToBoolValue (p , cmd , storagesFlag )
136+ userRoles := flags .FlagToBoolValue (p , cmd , userRolesFlag )
137+ dbCollations := flags .FlagToBoolValue (p , cmd , dbCollationsFlag )
138+ dbCompatibilities := flags .FlagToBoolValue (p , cmd , dbCompatibilitiesFlag )
139+
103140 flavorId := flags .FlagToStringPointer (p , cmd , flavorIdFlag )
141+ instanceId := flags .FlagToStringPointer (p , cmd , instanceIdFlag )
104142
105- if ! flavors && ! versions && ! storages {
143+ if ! flavors && ! versions && ! storages && ! userRoles && ! dbCollations && ! dbCompatibilities {
106144 return nil , fmt .Errorf ("%s\n \n %s" ,
107145 "please specify at least one category for which to list the available options." ,
108146 "Get details on the available flags by re-running your command with the --help flag." )
@@ -115,12 +153,23 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) {
115153 " $ stackit sqlserverflex options --flavors" )
116154 }
117155
156+ if (userRoles || dbCollations || dbCompatibilities ) && instanceId == nil {
157+ return nil , fmt .Errorf ("%s\n \n %s\n %s" ,
158+ `please specify an instance ID to show user roles, database collations or database compatibilities for by setting the flag "--instance-id <INSTANCE_ID>".` ,
159+ "You can get the available instances and their IDs by running:" ,
160+ " $ stackit sqlserverflex instance list" )
161+ }
162+
118163 model := inputModel {
119- GlobalFlagModel : globalFlags ,
120- Flavors : flavors ,
121- Versions : versions ,
122- Storages : storages ,
123- FlavorId : flags .FlagToStringPointer (p , cmd , flavorIdFlag ),
164+ GlobalFlagModel : globalFlags ,
165+ Flavors : flavors ,
166+ Versions : versions ,
167+ Storages : storages ,
168+ UserRoles : userRoles ,
169+ DBCollations : dbCollations ,
170+ DBCompatibilities : dbCompatibilities ,
171+ FlavorId : flavorId ,
172+ InstanceId : instanceId ,
124173 }
125174
126175 if p .IsVerbosityDebug () {
@@ -139,12 +188,18 @@ type sqlServerFlexOptionsClient interface {
139188 ListFlavorsExecute (ctx context.Context , projectId string ) (* sqlserverflex.ListFlavorsResponse , error )
140189 ListVersionsExecute (ctx context.Context , projectId string ) (* sqlserverflex.ListVersionsResponse , error )
141190 ListStoragesExecute (ctx context.Context , projectId , flavorId string ) (* sqlserverflex.ListStoragesResponse , error )
191+ ListRolesExecute (ctx context.Context , projectId string , instanceId string ) (* sqlserverflex.ListRolesResponse , error )
192+ ListCollationsExecute (ctx context.Context , projectId string , instanceId string ) (* sqlserverflex.ListCollationsResponse , error )
193+ ListCompatibilityExecute (ctx context.Context , projectId string , instanceId string ) (* sqlserverflex.ListCompatibilityResponse , error )
142194}
143195
144196func buildAndExecuteRequest (ctx context.Context , p * print.Printer , model * inputModel , apiClient sqlServerFlexOptionsClient ) error {
145197 var flavors * sqlserverflex.ListFlavorsResponse
146198 var versions * sqlserverflex.ListVersionsResponse
147199 var storages * sqlserverflex.ListStoragesResponse
200+ var userRoles * sqlserverflex.ListRolesResponse
201+ var dbCollations * sqlserverflex.ListCollationsResponse
202+ var dbCompatibilities * sqlserverflex.ListCompatibilityResponse
148203 var err error
149204
150205 if model .Flavors {
@@ -165,11 +220,29 @@ func buildAndExecuteRequest(ctx context.Context, p *print.Printer, model *inputM
165220 return fmt .Errorf ("get SQL Server Flex storages: %w" , err )
166221 }
167222 }
223+ if model .UserRoles {
224+ userRoles , err = apiClient .ListRolesExecute (ctx , model .ProjectId , * model .InstanceId )
225+ if err != nil {
226+ return fmt .Errorf ("get SQL Server Flex user roles: %w" , err )
227+ }
228+ }
229+ if model .DBCollations {
230+ dbCollations , err = apiClient .ListCollationsExecute (ctx , model .ProjectId , * model .InstanceId )
231+ if err != nil {
232+ return fmt .Errorf ("get SQL Server Flex DB collations: %w" , err )
233+ }
234+ }
235+ if model .DBCompatibilities {
236+ dbCompatibilities , err = apiClient .ListCompatibilityExecute (ctx , model .ProjectId , * model .InstanceId )
237+ if err != nil {
238+ return fmt .Errorf ("get SQL Server Flex DB compatibilities: %w" , err )
239+ }
240+ }
168241
169- return outputResult (p , model , flavors , versions , storages )
242+ return outputResult (p , model , flavors , versions , storages , userRoles , dbCollations , dbCompatibilities )
170243}
171244
172- func outputResult (p * print.Printer , model * inputModel , flavors * sqlserverflex.ListFlavorsResponse , versions * sqlserverflex.ListVersionsResponse , storages * sqlserverflex.ListStoragesResponse ) error {
245+ func outputResult (p * print.Printer , model * inputModel , flavors * sqlserverflex.ListFlavorsResponse , versions * sqlserverflex.ListVersionsResponse , storages * sqlserverflex.ListStoragesResponse , userRoles * sqlserverflex. ListRolesResponse , dbCollations * sqlserverflex. ListCollationsResponse , dbCompatibilities * sqlserverflex. ListCompatibilityResponse ) error {
173246 options := & options {}
174247 if flavors != nil {
175248 options .Flavors = flavors .Flavors
@@ -183,6 +256,24 @@ func outputResult(p *print.Printer, model *inputModel, flavors *sqlserverflex.Li
183256 Storages : storages ,
184257 }
185258 }
259+ if userRoles != nil && model .InstanceId != nil {
260+ options .UserRoles = & instanceUserRoles {
261+ InstanceId : * model .InstanceId ,
262+ UserRoles : * userRoles .Roles ,
263+ }
264+ }
265+ if dbCollations != nil && model .InstanceId != nil {
266+ options .DBCollations = & instanceDBCollations {
267+ InstanceId : * model .InstanceId ,
268+ DBCollations : * dbCollations .Collations ,
269+ }
270+ }
271+ if dbCompatibilities != nil && model .InstanceId != nil {
272+ options .DBCompatibilities = & instanceDBCompatibilities {
273+ InstanceId : * model .InstanceId ,
274+ DBCompatibilities : * dbCompatibilities .Compatibilities ,
275+ }
276+ }
186277
187278 switch model .OutputFormat {
188279 case print .JSONOutputFormat :
@@ -216,6 +307,15 @@ func outputResultAsTable(p *print.Printer, model *inputModel, options *options)
216307 if model .Storages {
217308 content += renderStorages (options .Storages .Storages )
218309 }
310+ if model .UserRoles {
311+ content += renderUserRoles (options .UserRoles )
312+ }
313+ if model .DBCollations {
314+ content += renderDBCollations (options .DBCollations )
315+ }
316+ if model .DBCompatibilities {
317+ content += renderDBCompatibilities (options .DBCompatibilities )
318+ }
219319
220320 err := p .PagerDisplay (content )
221321 if err != nil {
@@ -271,3 +371,45 @@ func renderStorages(resp *sqlserverflex.ListStoragesResponse) string {
271371 table .EnableAutoMergeOnColumns (1 , 2 , 3 )
272372 return table .Render ()
273373}
374+
375+ func renderUserRoles (roles * instanceUserRoles ) string {
376+ if len (roles .UserRoles ) == 0 {
377+ return ""
378+ }
379+
380+ table := tables .NewTable ()
381+ table .SetTitle ("User Roles" )
382+ table .SetHeader ("ROLE" )
383+ for i := range roles .UserRoles {
384+ table .AddRow (roles .UserRoles [i ])
385+ }
386+ return table .Render ()
387+ }
388+
389+ func renderDBCollations (dbCollations * instanceDBCollations ) string {
390+ if len (dbCollations .DBCollations ) == 0 {
391+ return ""
392+ }
393+
394+ table := tables .NewTable ()
395+ table .SetTitle ("DB Collations" )
396+ table .SetHeader ("NAME" , "DESCRIPTION" )
397+ for i := range dbCollations .DBCollations {
398+ table .AddRow (* dbCollations .DBCollations [i ].CollationName , * dbCollations .DBCollations [i ].Description )
399+ }
400+ return table .Render ()
401+ }
402+
403+ func renderDBCompatibilities (dbCompatibilities * instanceDBCompatibilities ) string {
404+ if len (dbCompatibilities .DBCompatibilities ) == 0 {
405+ return ""
406+ }
407+
408+ table := tables .NewTable ()
409+ table .SetTitle ("DB Compatibilities" )
410+ table .SetHeader ("COMPATIBILITY LEVEL" , "DESCRIPTION" )
411+ for i := range dbCompatibilities .DBCompatibilities {
412+ table .AddRow (* dbCompatibilities .DBCompatibilities [i ].CompatibilityLevel , * dbCompatibilities .DBCompatibilities [i ].Description )
413+ }
414+ return table .Render ()
415+ }
0 commit comments