Skip to content

Add sqlserverflex user create and reset-password commands #384

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

Merged
merged 9 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/stackit_beta_sqlserverflex.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ stackit beta sqlserverflex [flags]
* [stackit beta](./stackit_beta.md) - Contains beta STACKIT CLI commands
* [stackit beta sqlserverflex instance](./stackit_beta_sqlserverflex_instance.md) - Provides functionality for SQLServer Flex instances
* [stackit beta sqlserverflex options](./stackit_beta_sqlserverflex_options.md) - Lists SQL Server Flex options
* [stackit beta sqlserverflex user](./stackit_beta_sqlserverflex_user.md) - Provides functionality for SQLServer Flex users

4 changes: 2 additions & 2 deletions docs/stackit_beta_sqlserverflex_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ stackit beta sqlserverflex options [flags]
List SQL Server Flex available versions
$ stackit beta sqlserverflex options --versions

List SQL Server Flex storage options for a given flavor. The flavor ID can be retrieved by running "$ stackit sqlserverflex options --flavors"
List SQL Server Flex storage options for a given flavor. The flavor ID can be retrieved by running "$ stackit beta sqlserverflex options --flavors"
$ stackit beta sqlserverflex options --storages --flavor-id <FLAVOR_ID>

List SQL Server Flex user roles and database compatibilities for a given instance. The IDs of existing instances can be obtained by running "$ stackit sqlserverflex instance list"
List SQL Server Flex user roles and database compatibilities for a given instance. The IDs of existing instances can be obtained by running "$ stackit beta sqlserverflex instance list"
$ stackit beta sqlserverflex options --user-roles --db-compatibilities --instance-id <INSTANCE_ID>
```

Expand Down
34 changes: 34 additions & 0 deletions docs/stackit_beta_sqlserverflex_user.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## stackit beta sqlserverflex user

Provides functionality for SQLServer Flex users

### Synopsis

Provides functionality for SQLServer Flex users.

```
stackit beta sqlserverflex user [flags]
```

### Options

```
-h, --help Help for "stackit beta sqlserverflex user"
```

### Options inherited from parent commands

```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
-p, --project-id string Project ID
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit beta sqlserverflex](./stackit_beta_sqlserverflex.md) - Provides functionality for SQLServer Flex
* [stackit beta sqlserverflex user create](./stackit_beta_sqlserverflex_user_create.md) - Creates an SQLServer Flex user
* [stackit beta sqlserverflex user reset-password](./stackit_beta_sqlserverflex_user_reset-password.md) - Resets the password of an SQLServer Flex user

50 changes: 50 additions & 0 deletions docs/stackit_beta_sqlserverflex_user_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## stackit beta sqlserverflex user create

Creates an SQLServer Flex user

### Synopsis

Creates an SQLServer Flex user for an instance.
The password is only visible upon creation and cannot be retrieved later.
Alternatively, you can reset the password and access the new one by running:
$ stackit beta sqlserverflex user reset-password USER_ID --instance-id INSTANCE_ID
Please refer to https://docs.stackit.cloud/stackit/en/creating-logins-and-users-in-sqlserver-flex-instances-210862358.html for additional information.

```
stackit beta sqlserverflex user create [flags]
```

### Examples

```
Create an SQLServer Flex user for instance with ID "xxx" and specify the username, role and database
$ stackit beta sqlserverflex user create --instance-id xxx --username johndoe --roles my-role --database my-database

Create an SQLServer Flex user for instance with ID "xxx", specifying multiple roles
$ stackit beta sqlserverflex user create --instance-id xxx --username johndoe --roles "my-role-1,my-role-2
```

### Options

```
--database string Default database for the user
-h, --help Help for "stackit beta sqlserverflex user create"
--instance-id string ID of the instance
--roles strings Roles of the user
--username string Username of the user
```

### Options inherited from parent commands

```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
-p, --project-id string Project ID
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit beta sqlserverflex user](./stackit_beta_sqlserverflex_user.md) - Provides functionality for SQLServer Flex users

41 changes: 41 additions & 0 deletions docs/stackit_beta_sqlserverflex_user_reset-password.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## stackit beta sqlserverflex user reset-password

Resets the password of an SQLServer Flex user

### Synopsis

Resets the password of an SQLServer Flex user.
sThe new password is visible after resetting and cannot be retrieved later.

```
stackit beta sqlserverflex user reset-password USER_ID [flags]
```

### Examples

```
Reset the password of an SQLServer Flex user with ID "xxx" of instance with ID "yyy"
$ stackit beta sqlserverflex user reset-password xxx --instance-id yyy
```

### Options

```
-h, --help Help for "stackit beta sqlserverflex user reset-password"
--instance-id string ID of the instance
```

### Options inherited from parent commands

```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
-p, --project-id string Project ID
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit beta sqlserverflex user](./stackit_beta_sqlserverflex_user.md) - Provides functionality for SQLServer Flex users

4 changes: 2 additions & 2 deletions docs/stackit_mongodbflex_user_describe.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ stackit mongodbflex user describe USER_ID [flags]

```
Get details of a MongoDB Flex user with ID "xxx" of instance with ID "yyy"
$ stackit mongodbflex user list xxx --instance-id yyy
$ stackit mongodbflex user describe xxx --instance-id yyy

Get details of a MongoDB Flex user with ID "xxx" of instance with ID "yyy" in JSON format
$ stackit mongodbflex user list xxx --instance-id yyy --output-format json
$ stackit mongodbflex user describe xxx --instance-id yyy --output-format json
```

### Options
Expand Down
4 changes: 2 additions & 2 deletions docs/stackit_postgresflex_user_describe.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ stackit postgresflex user describe USER_ID [flags]

```
Get details of a PostgreSQL Flex user with ID "xxx" of instance with ID "yyy"
$ stackit postgresflex user list xxx --instance-id yyy
$ stackit postgresflex user describe xxx --instance-id yyy

Get details of a PostgreSQL Flex user with ID "xxx" of instance with ID "yyy" in JSON format
$ stackit postgresflex user list xxx --instance-id yyy --output-format json
$ stackit postgresflex user describe xxx --instance-id yyy --output-format json
```

### Options
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/beta/sqlserverflex/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ func NewCmd(p *print.Printer) *cobra.Command {
`List SQL Server Flex available versions`,
"$ stackit beta sqlserverflex options --versions"),
examples.NewExample(
`List SQL Server Flex storage options for a given flavor. The flavor ID can be retrieved by running "$ stackit sqlserverflex options --flavors"`,
`List SQL Server Flex storage options for a given flavor. The flavor ID can be retrieved by running "$ stackit beta sqlserverflex options --flavors"`,
"$ stackit beta sqlserverflex options --storages --flavor-id <FLAVOR_ID>"),
examples.NewExample(
`List SQL Server Flex user roles and database compatibilities for a given instance. The IDs of existing instances can be obtained by running "$ stackit sqlserverflex instance list"`,
`List SQL Server Flex user roles and database compatibilities for a given instance. The IDs of existing instances can be obtained by running "$ stackit beta sqlserverflex instance list"`,
"$ stackit beta sqlserverflex options --user-roles --db-compatibilities --instance-id <INSTANCE_ID>"),
),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
2 changes: 2 additions & 0 deletions internal/cmd/beta/sqlserverflex/sqlserverflex.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sqlserverflex
import (
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/sqlserverflex/instance"
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/sqlserverflex/options"
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/sqlserverflex/user"
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
Expand All @@ -25,4 +26,5 @@ func NewCmd(p *print.Printer) *cobra.Command {
func addSubcommands(cmd *cobra.Command, p *print.Printer) {
cmd.AddCommand(instance.NewCmd(p))
cmd.AddCommand(options.NewCmd(p))
cmd.AddCommand(user.NewCmd(p))
}
194 changes: 194 additions & 0 deletions internal/cmd/beta/sqlserverflex/user/create/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package create

import (
"context"
"encoding/json"
"fmt"

"github.com/goccy/go-yaml"
"github.com/spf13/cobra"
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
"github.com/stackitcloud/stackit-cli/internal/pkg/services/sqlserverflex/client"
sqlserverflexUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/sqlserverflex/utils"
"github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex"
)

const (
instanceIdFlag = "instance-id"
usernameFlag = "username"
databaseFlag = "database"
rolesFlag = "roles"
)

type inputModel struct {
*globalflags.GlobalFlagModel

InstanceId string
Username *string
Database *string
Roles *[]string
}

func NewCmd(p *print.Printer) *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Creates an SQLServer Flex user",
Long: fmt.Sprintf("%s\n%s\n%s\n%s\n%s",
"Creates an SQLServer Flex user for an instance.",
"The password is only visible upon creation and cannot be retrieved later.",
"Alternatively, you can reset the password and access the new one by running:",
" $ stackit beta sqlserverflex user reset-password USER_ID --instance-id INSTANCE_ID",
"Please refer to https://docs.stackit.cloud/stackit/en/creating-logins-and-users-in-sqlserver-flex-instances-210862358.html for additional information.",
),
Example: examples.Build(
examples.NewExample(
`Create an SQLServer Flex user for instance with ID "xxx" and specify the username, role and database`,
"$ stackit beta sqlserverflex user create --instance-id xxx --username johndoe --roles my-role --database my-database"),
examples.NewExample(
`Create an SQLServer Flex user for instance with ID "xxx", specifying multiple roles`,
`$ stackit beta sqlserverflex user create --instance-id xxx --username johndoe --roles "my-role-1,my-role-2`),
),
Args: args.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
model, err := parseInput(p, cmd)
if err != nil {
return err
}

// Configure API client
apiClient, err := client.ConfigureClient(p)
if err != nil {
return err
}

instanceLabel, err := sqlserverflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.InstanceId)
if err != nil {
p.Debug(print.ErrorLevel, "get instance name: %v", err)
instanceLabel = model.InstanceId
}

if !model.AssumeYes {
prompt := fmt.Sprintf("Are you sure you want to create a user for instance %q?", instanceLabel)
err = p.PromptForConfirmation(prompt)
if err != nil {
return err
}
}

// Call API
req := buildRequest(ctx, model, apiClient)
resp, err := req.Execute()
if err != nil {
return fmt.Errorf("create SQLServer Flex user: %w", err)
}
user := resp.Item

return outputResult(p, model, instanceLabel, user)
},
}

configureFlags(cmd)
return cmd
}

func configureFlags(cmd *cobra.Command) {
cmd.Flags().Var(flags.UUIDFlag(), instanceIdFlag, "ID of the instance")
cmd.Flags().String(usernameFlag, "", "Username of the user")
cmd.Flags().String(databaseFlag, "", "Default database for the user")
cmd.Flags().StringSlice(rolesFlag, []string{}, "Roles of the user")

err := flags.MarkFlagsRequired(cmd, instanceIdFlag, usernameFlag)
cobra.CheckErr(err)
}

func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) {
globalFlags := globalflags.Parse(p, cmd)
if globalFlags.ProjectId == "" {
return nil, &errors.ProjectIdError{}
}

model := inputModel{
GlobalFlagModel: globalFlags,
InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag),
Username: flags.FlagToStringPointer(p, cmd, usernameFlag),
Database: flags.FlagToStringPointer(p, cmd, databaseFlag),
Roles: flags.FlagToStringSlicePointer(p, cmd, rolesFlag),
}

if p.IsVerbosityDebug() {
modelStr, err := print.BuildDebugStrFromInputModel(model)
if err != nil {
p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err)
} else {
p.Debug(print.DebugLevel, "parsed input values: %s", modelStr)
}
}

return &model, nil
}

func buildRequest(ctx context.Context, model *inputModel, apiClient *sqlserverflex.APIClient) sqlserverflex.ApiCreateUserRequest {
req := apiClient.CreateUser(ctx, model.ProjectId, model.InstanceId)

var roles []sqlserverflex.Role
if model.Roles != nil {
for _, r := range *model.Roles {
roles = append(roles, sqlserverflex.Role(r))
}
}

req = req.CreateUserPayload(sqlserverflex.CreateUserPayload{
Username: model.Username,
Database: model.Database,
Roles: &roles,
})
return req
}

func outputResult(p *print.Printer, model *inputModel, instanceLabel string, user *sqlserverflex.User) error {
switch model.OutputFormat {
case print.JSONOutputFormat:
details, err := json.MarshalIndent(user, "", " ")
if err != nil {
return fmt.Errorf("marshal SQLServer Flex user: %w", err)
}
p.Outputln(string(details))

return nil
case print.YAMLOutputFormat:
details, err := yaml.MarshalWithOptions(user, yaml.IndentSequence(true))
if err != nil {
return fmt.Errorf("marshal SQLServer Flex user: %w", err)
}
p.Outputln(string(details))

return nil
default:
p.Outputf("Created user for instance %q. User ID: %s\n\n", instanceLabel, *user.Id)
p.Outputf("Username: %s\n", *user.Username)
p.Outputf("Password: %s\n", *user.Password)
if user.Roles != nil && len(*user.Roles) != 0 {
p.Outputf("Roles: %v\n", *user.Roles)
}
if user.Database != nil && *user.Database != "" {
p.Outputf("Database: %s\n", *user.Database)
}
if user.Host != nil && *user.Host != "" {
p.Outputf("Host: %s\n", *user.Host)
}
if user.Port != nil {
p.Outputf("Port: %d\n", *user.Port)
}
if user.Uri != nil && *user.Uri != "" {
p.Outputf("URI: %s\n", *user.Uri)
}

return nil
}
}
Loading