-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathcreate.go
145 lines (118 loc) · 4.45 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package create
import (
"context"
"fmt"
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
"github.com/stackitcloud/stackit-cli/internal/pkg/confirm"
cliErr "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/projectname"
"github.com/stackitcloud/stackit-cli/internal/pkg/services/secrets-manager/client"
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
"github.com/stackitcloud/stackit-sdk-go/services/secretsmanager"
"github.com/spf13/cobra"
)
const (
instanceNameFlag = "name"
aclFlag = "acl"
)
type inputModel struct {
*globalflags.GlobalFlagModel
InstanceName *string
Acls *[]string
}
func NewCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Creates a Secrets Manager instance",
Long: "Creates a Secrets Manager instance.",
Args: args.NoArgs,
Example: examples.Build(
examples.NewExample(
`Create a Secrets Manager instance with name "my-instance"`,
`$ stackit secrets-manager instance create --name my-instance`),
examples.NewExample(
`Create a Secrets Manager instance with name "my-instance" and specify IP range which is allowed to access it`,
`$ stackit secrets-manager instance create --name my-instance --acl 1.2.3.0/24`),
),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
model, err := parseInput(cmd)
if err != nil {
return err
}
// Configure API client
apiClient, err := client.ConfigureClient(cmd)
if err != nil {
return err
}
projectLabel, err := projectname.GetProjectName(ctx, cmd)
if err != nil {
projectLabel = model.ProjectId
}
if !model.AssumeYes {
prompt := fmt.Sprintf("Are you sure you want to create a Secrets Manager instance for project %q?", projectLabel)
err = confirm.PromptForConfirmation(cmd, prompt)
if err != nil {
return err
}
}
// Call API to create instance
req := buildCreateInstanceRequest(ctx, model, apiClient)
resp, err := req.Execute()
if err != nil {
return fmt.Errorf("create Secrets Manager instance: %w", err)
}
instanceId := *resp.Id
// Call API to create ACLs for instance, if ACLs are provided
if model.Acls != nil {
updateReq := buildUpdateACLsRequest(ctx, model, instanceId, apiClient)
err = updateReq.Execute()
if err != nil {
return fmt.Errorf(`the Secrets Manager instance was successfully created, but the configuration of the ACLs failed. The default behavior is to have no ACL.
If you want to retry configuring the ACLs, you can do it via:
$ stackit secrets-manager instance update %s --acl %s`, instanceId, *model.Acls)
}
}
cmd.Printf("Created instance for project %q. Instance ID: %s\n", projectLabel, instanceId)
return nil
},
}
configureFlags(cmd)
return cmd
}
func configureFlags(cmd *cobra.Command) {
cmd.Flags().StringP(instanceNameFlag, "n", "", "Instance name")
cmd.Flags().Var(flags.CIDRSliceFlag(), aclFlag, "List of IP networks in CIDR notation which are allowed to access this instance")
err := flags.MarkFlagsRequired(cmd, instanceNameFlag)
cobra.CheckErr(err)
}
func parseInput(cmd *cobra.Command) (*inputModel, error) {
globalFlags := globalflags.Parse(cmd)
if globalFlags.ProjectId == "" {
return nil, &cliErr.ProjectIdError{}
}
return &inputModel{
GlobalFlagModel: globalFlags,
InstanceName: flags.FlagToStringPointer(cmd, instanceNameFlag),
Acls: flags.FlagToStringSlicePointer(cmd, aclFlag),
}, nil
}
func buildCreateInstanceRequest(ctx context.Context, model *inputModel, apiClient *secretsmanager.APIClient) secretsmanager.ApiCreateInstanceRequest {
req := apiClient.CreateInstance(ctx, model.ProjectId)
req = req.CreateInstancePayload(secretsmanager.CreateInstancePayload{
Name: model.InstanceName,
})
return req
}
func buildUpdateACLsRequest(ctx context.Context, model *inputModel, instanceId string, apiClient *secretsmanager.APIClient) secretsmanager.ApiUpdateACLsRequest {
req := apiClient.UpdateACLs(ctx, model.ProjectId, instanceId)
cidrs := make([]secretsmanager.AclUpdate, len(*model.Acls))
for i, acl := range *model.Acls {
cidrs[i] = secretsmanager.AclUpdate{Cidr: utils.Ptr(acl)}
}
req = req.UpdateACLsPayload(secretsmanager.UpdateACLsPayload{Cidrs: &cidrs})
return req
}