Skip to content

Commit abfc176

Browse files
committed
feat(automation): onboard volume automation template command
relates to STACKITCLI-349
1 parent 7cae103 commit abfc176

15 files changed

Lines changed: 812 additions & 0 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/stackitcloud/stackit-sdk-go/services/alb v0.17.1
2020
github.com/stackitcloud/stackit-sdk-go/services/albwaf v0.13.2
2121
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.15.3
22+
github.com/stackitcloud/stackit-sdk-go/services/automation v0.1.1
2223
github.com/stackitcloud/stackit-sdk-go/services/cdn v1.21.0
2324
github.com/stackitcloud/stackit-sdk-go/services/dns v0.22.1
2425
github.com/stackitcloud/stackit-sdk-go/services/edge v0.13.2

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,8 @@ github.com/stackitcloud/stackit-sdk-go/services/albwaf v0.13.2 h1:zY0ArhTg++8oOA
616616
github.com/stackitcloud/stackit-sdk-go/services/albwaf v0.13.2/go.mod h1:4M9G1I64kZwlXO32ZoIpt0GAN4SpZ1SYerwCVVIBGoE=
617617
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.15.3 h1:YEuymF48gnBNqBsraBN5pycBDEyXcFYy/2bCdF+H3eY=
618618
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.15.3/go.mod h1:T/JF25XGJ3GqER/1L2N//DgY8x5tY7gA3N+/0nvmOWY=
619+
github.com/stackitcloud/stackit-sdk-go/services/automation v0.1.1 h1:naKG2lRw9ALCNaaJabhgtuCwSBVyOOlIX3NPkIFX1i0=
620+
github.com/stackitcloud/stackit-sdk-go/services/automation v0.1.1/go.mod h1:1vv2SZorcHJKxEPV15CnTDhavV+NcYSNjAX7cZGX31k=
619621
github.com/stackitcloud/stackit-sdk-go/services/cdn v1.21.0 h1:lCs1eq/OOTdwGrrkxkJ8qCnS6yLM4XZhznpML3nd1NI=
620622
github.com/stackitcloud/stackit-sdk-go/services/cdn v1.21.0/go.mod h1:NBgvZH5ekJ2hFCNI480C9MdJsa4989YGC1YgX5ELA48=
621623
github.com/stackitcloud/stackit-sdk-go/services/dns v0.22.1 h1:vC0GpKVKH1Tce9VNyZTMWbheyGGS9a9GZWv6H5/z4Ek=

internal/cmd/beta/beta.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/edge"
1212
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/intake"
1313
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/sfs"
14+
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/volume"
1415
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/vpn"
1516
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
1617
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
@@ -42,6 +43,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
4243
}
4344

4445
func addSubcommands(cmd *cobra.Command, params *types.CmdParams) {
46+
cmd.AddCommand(volume.NewCmd(params))
4547
cmd.AddCommand(sfs.NewCmd(params))
4648
cmd.AddCommand(alb.NewCmd(params))
4749
cmd.AddCommand(albwaf.NewCmd(params))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package automation
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/volume/automation/template"
6+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
8+
)
9+
10+
func NewCmd(params *types.CmdParams) *cobra.Command {
11+
cmd := &cobra.Command{
12+
Use: "automation",
13+
Short: "Provides functionality for Volume Automation",
14+
Long: "Provides functionality for Volume Automation.",
15+
Args: cobra.NoArgs,
16+
Run: utils.CmdHelp,
17+
}
18+
addSubcommands(cmd, params)
19+
return cmd
20+
}
21+
22+
func addSubcommands(cmd *cobra.Command, params *types.CmdParams) {
23+
cmd.AddCommand(template.NewCmd(params))
24+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package describe
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/spf13/cobra"
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
10+
cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
15+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/automation/client"
16+
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
17+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
18+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
19+
automation "github.com/stackitcloud/stackit-sdk-go/services/automation/v1betaapi"
20+
)
21+
22+
const (
23+
templateIdArg = "TEMPLATE_ID"
24+
)
25+
26+
type inputModel struct {
27+
*globalflags.GlobalFlagModel
28+
TemplateId string
29+
}
30+
31+
func NewCmd(params *types.CmdParams) *cobra.Command {
32+
cmd := &cobra.Command{
33+
Use: "describe",
34+
Short: "Shows details of a Volume Automation Template",
35+
Long: "Shows details of a Volume Automation Template.",
36+
Args: args.SingleArg(templateIdArg, utils.ValidateUUID),
37+
Example: examples.Build(
38+
examples.NewExample(
39+
`Describe the Volume Automation Template with ID "xxx"`,
40+
"$ stackit beta volume automation template describe xxx"),
41+
),
42+
RunE: func(cmd *cobra.Command, args []string) error {
43+
ctx := context.Background()
44+
45+
model, err := parseInput(params.Printer, cmd, args)
46+
if err != nil {
47+
return err
48+
}
49+
50+
// Configure API client
51+
apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion)
52+
if err != nil {
53+
return err
54+
}
55+
56+
// Call API
57+
resp, err := buildRequest(ctx, model, apiClient).Execute()
58+
if err != nil {
59+
return fmt.Errorf("describe volume automation template: %w", err)
60+
}
61+
62+
// Get projectLabel
63+
projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd)
64+
if err != nil {
65+
params.Printer.Debug(print.ErrorLevel, "get project name: %v", err)
66+
projectLabel = model.ProjectId
67+
} else if projectLabel == "" {
68+
projectLabel = model.ProjectId
69+
}
70+
71+
return outputResult(params.Printer, model.OutputFormat, model.TemplateId, projectLabel, resp)
72+
},
73+
}
74+
return cmd
75+
}
76+
77+
func buildRequest(ctx context.Context, model *inputModel, apiClient *automation.APIClient) automation.ApiGetVolumeTemplateRequest {
78+
req := apiClient.DefaultAPI.GetVolumeTemplate(ctx, model.ProjectId, model.Region, model.TemplateId)
79+
return req
80+
}
81+
82+
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) {
83+
templateId := inputArgs[0]
84+
85+
globalFlags := globalflags.Parse(p, cmd)
86+
if globalFlags.ProjectId == "" {
87+
return nil, &cliErr.ProjectIdError{}
88+
}
89+
90+
model := inputModel{
91+
GlobalFlagModel: globalFlags,
92+
TemplateId: templateId,
93+
}
94+
95+
p.DebugInputModel(model)
96+
return &model, nil
97+
}
98+
99+
func outputResult(p *print.Printer, outputFormat, templateId, projectLabel string, template *automation.GetVolumeTemplateResponse) error {
100+
return p.OutputResult(outputFormat, template, func() error {
101+
if template == nil {
102+
p.Outputf("Volume automation template %q not found in project %q\n", templateId, projectLabel)
103+
return nil
104+
}
105+
106+
var content []tables.Table
107+
108+
table := tables.NewTable()
109+
110+
table.SetTitle("Volume Automation Template")
111+
table.AddRow("ID", template.Id)
112+
table.AddSeparator()
113+
table.AddRow("NAME", template.Name)
114+
table.AddSeparator()
115+
table.AddRow("DESCRIPTION", template.Description)
116+
table.AddSeparator()
117+
if template.Input != nil {
118+
table.AddRow("INPUT KIND", template.Input.Kind)
119+
table.AddSeparator()
120+
}
121+
122+
content = append(content, table)
123+
124+
if template.Output != nil && len(template.Output.Steps) > 0 {
125+
outputStepsTable := tables.NewTable()
126+
outputStepsTable.SetTitle("OUTPUT STEPS")
127+
for _, step := range template.Output.Steps {
128+
outputStepsTable.AddRow("NAME", step.Name)
129+
outputStepsTable.AddSeparator()
130+
if step.Result != nil {
131+
if step.Result.GetVolumeIDsResult != nil {
132+
volumeIds := ""
133+
if len(step.Result.GetVolumeIDsResult.VolumeIDs) > 0 {
134+
volumeIds = strings.Join(step.Result.GetVolumeIDsResult.VolumeIDs, "\n")
135+
}
136+
outputStepsTable.AddRow("VOLUME IDS", volumeIds)
137+
outputStepsTable.AddSeparator()
138+
}
139+
if step.Result.CreateSnapshotsResult != nil {
140+
createdSnapshotIds := ""
141+
if len(step.Result.CreateSnapshotsResult.CreatedSnapshotIDs) > 0 {
142+
createdSnapshotIds = strings.Join(step.Result.CreateSnapshotsResult.CreatedSnapshotIDs, "\n")
143+
}
144+
outputStepsTable.AddRow("CREATED SNAPSHOT IDS", createdSnapshotIds)
145+
outputStepsTable.AddSeparator()
146+
}
147+
}
148+
}
149+
content = append(content, outputStepsTable)
150+
}
151+
152+
err := tables.DisplayTables(p, content)
153+
if err != nil {
154+
return fmt.Errorf("render tables: %w", err)
155+
}
156+
return nil
157+
})
158+
}

0 commit comments

Comments
 (0)