Skip to content

Commit 0cb21d8

Browse files
committed
feat(observabiltiy): Onboard ACL commands
STACKITCLI-552 Signed-off-by: Alexander Dahmen <alexander.dahmen@inovex.de>
1 parent bc4b561 commit 0cb21d8

10 files changed

Lines changed: 893 additions & 0 deletions

File tree

‎docs/stackit_observability.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ stackit observability [flags]
3030
### SEE ALSO
3131

3232
* [stackit](./stackit.md) - Manage STACKIT resources using the command line
33+
* [stackit observability acl](./stackit_observability_acl.md) - Provides functionality for ACLs of Observability instances
3334
* [stackit observability credentials](./stackit_observability_credentials.md) - Provides functionality for Observability credentials
3435
* [stackit observability grafana](./stackit_observability_grafana.md) - Provides functionality for the Grafana configuration of Observability instances
3536
* [stackit observability instance](./stackit_observability_instance.md) - Provides functionality for Observability instances

‎docs/stackit_observability_acl.md‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## stackit observability acl
2+
3+
Provides functionality for ACLs of Observability instances
4+
5+
### Synopsis
6+
7+
Provides functionality for access control lists (ACLs) of Observability instances.
8+
9+
```
10+
stackit observability acl [flags]
11+
```
12+
13+
### Options
14+
15+
```
16+
-h, --help Help for "stackit observability acl"
17+
```
18+
19+
### Options inherited from parent commands
20+
21+
```
22+
-y, --assume-yes If set, skips all confirmation prompts
23+
--async If set, runs the command asynchronously
24+
-o, --output-format string Output format, (one of: [json, pretty, none, yaml])
25+
-p, --project-id string Project ID
26+
--region string Target region for region-specific requests
27+
--verbosity string Verbosity of the CLI, (one of: [debug, info, warning, error]) (default "info")
28+
```
29+
30+
### SEE ALSO
31+
32+
* [stackit observability](./stackit_observability.md) - Provides functionality for Observability
33+
* [stackit observability acl list](./stackit_observability_acl_list.md) - Lists all ACLs of an Observability instance
34+
* [stackit observability acl update](./stackit_observability_acl_update.md) - Updates the ACLs of an Observability instance
35+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## stackit observability acl list
2+
3+
Lists all ACLs of an Observability instance
4+
5+
### Synopsis
6+
7+
Lists all IP networks in CIDR notation which are allowed to access an Observability instance.
8+
9+
```
10+
stackit observability acl list [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
List all ACLs of Observability instance "xxx"
17+
$ stackit observability acl list --instance-id xxx
18+
19+
List all ACLs of Observability instance "xxx" in JSON format
20+
$ stackit observability acl list --instance-id xxx --output-format json
21+
22+
List up to 10 ACLs of Observability instance "xxx"
23+
$ stackit observability acl list --instance-id xxx --limit 10
24+
```
25+
26+
### Options
27+
28+
```
29+
-h, --help Help for "stackit observability acl list"
30+
--instance-id string Instance ID
31+
--limit int Maximum number of entries to list
32+
```
33+
34+
### Options inherited from parent commands
35+
36+
```
37+
-y, --assume-yes If set, skips all confirmation prompts
38+
--async If set, runs the command asynchronously
39+
-o, --output-format string Output format, (one of: [json, pretty, none, yaml])
40+
-p, --project-id string Project ID
41+
--region string Target region for region-specific requests
42+
--verbosity string Verbosity of the CLI, (one of: [debug, info, warning, error]) (default "info")
43+
```
44+
45+
### SEE ALSO
46+
47+
* [stackit observability acl](./stackit_observability_acl.md) - Provides functionality for ACLs of Observability instances
48+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## stackit observability acl update
2+
3+
Updates the ACLs of an Observability instance
4+
5+
### Synopsis
6+
7+
Updates the ACLs of an Observability instance.
8+
The provided list replaces all existing ACLs. An empty list removes all ACLs.
9+
10+
```
11+
stackit observability acl update [flags]
12+
```
13+
14+
### Examples
15+
16+
```
17+
Set the ACLs of Observability instance "xxx" to the IP networks "1.2.3.0/24" and "5.6.7.8/32"
18+
$ stackit observability acl update --instance-id xxx --acl 1.2.3.0/24,5.6.7.8/32
19+
20+
Remove all ACLs of Observability instance "xxx"
21+
$ stackit observability acl update --instance-id xxx --acl ""
22+
```
23+
24+
### Options
25+
26+
```
27+
--acl strings List of IP networks in CIDR notation which are allowed to access the instance. Replaces all existing ACLs, an empty value removes all ACLs (default [])
28+
-h, --help Help for "stackit observability acl update"
29+
--instance-id string Instance ID
30+
```
31+
32+
### Options inherited from parent commands
33+
34+
```
35+
-y, --assume-yes If set, skips all confirmation prompts
36+
--async If set, runs the command asynchronously
37+
-o, --output-format string Output format, (one of: [json, pretty, none, yaml])
38+
-p, --project-id string Project ID
39+
--region string Target region for region-specific requests
40+
--verbosity string Verbosity of the CLI, (one of: [debug, info, warning, error]) (default "info")
41+
```
42+
43+
### SEE ALSO
44+
45+
* [stackit observability acl](./stackit_observability_acl.md) - Provides functionality for ACLs of Observability instances
46+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package acl
2+
3+
import (
4+
"github.com/stackitcloud/stackit-cli/internal/cmd/observability/acl/list"
5+
"github.com/stackitcloud/stackit-cli/internal/cmd/observability/acl/update"
6+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
8+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
9+
10+
"github.com/spf13/cobra"
11+
)
12+
13+
func NewCmd(params *types.CmdParams) *cobra.Command {
14+
cmd := &cobra.Command{
15+
Use: "acl",
16+
Short: "Provides functionality for ACLs of Observability instances",
17+
Long: "Provides functionality for access control lists (ACLs) of Observability instances.",
18+
Args: args.NoArgs,
19+
Run: utils.CmdHelp,
20+
}
21+
addSubcommands(cmd, params)
22+
return cmd
23+
}
24+
25+
func addSubcommands(cmd *cobra.Command, params *types.CmdParams) {
26+
cmd.AddCommand(list.NewCmd(params))
27+
cmd.AddCommand(update.NewCmd(params))
28+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package list
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
8+
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
10+
"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/flags"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
15+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/observability/client"
16+
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
17+
18+
observabilityUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/observability/utils"
19+
20+
"github.com/spf13/cobra"
21+
observability "github.com/stackitcloud/stackit-sdk-go/services/observability/v1api"
22+
)
23+
24+
const (
25+
limitFlag = "limit"
26+
instanceIdFlag = "instance-id"
27+
)
28+
29+
type inputModel struct {
30+
*globalflags.GlobalFlagModel
31+
Limit *int64
32+
InstanceId string
33+
}
34+
35+
func NewCmd(params *types.CmdParams) *cobra.Command {
36+
cmd := &cobra.Command{
37+
Use: "list",
38+
Short: "Lists all ACLs of an Observability instance",
39+
Long: "Lists all IP networks in CIDR notation which are allowed to access an Observability instance.",
40+
Args: args.NoArgs,
41+
Example: examples.Build(
42+
examples.NewExample(
43+
`List all ACLs of Observability instance "xxx"`,
44+
"$ stackit observability acl list --instance-id xxx"),
45+
examples.NewExample(
46+
`List all ACLs of Observability instance "xxx" in JSON format`,
47+
"$ stackit observability acl list --instance-id xxx --output-format json"),
48+
examples.NewExample(
49+
`List up to 10 ACLs of Observability instance "xxx"`,
50+
"$ stackit observability acl list --instance-id xxx --limit 10"),
51+
),
52+
RunE: func(cmd *cobra.Command, args []string) error {
53+
ctx := context.Background()
54+
model, err := parseInput(params.Printer, cmd, args)
55+
if err != nil {
56+
return err
57+
}
58+
59+
// Configure API client
60+
apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion)
61+
if err != nil {
62+
return err
63+
}
64+
65+
// Call API
66+
req := buildRequest(ctx, model, apiClient.DefaultAPI)
67+
resp, err := req.Execute()
68+
if err != nil {
69+
return fmt.Errorf("get Observability instance ACLs: %w", err)
70+
}
71+
72+
acls := resp.GetAcl()
73+
74+
instanceLabel, err := observabilityUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.InstanceId, model.ProjectId)
75+
if err != nil || instanceLabel == "" {
76+
params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err)
77+
instanceLabel = model.InstanceId
78+
}
79+
80+
// Truncate output
81+
if model.Limit != nil && len(acls) > int(*model.Limit) {
82+
acls = acls[:*model.Limit]
83+
}
84+
85+
return outputResult(params.Printer, model.OutputFormat, instanceLabel, acls)
86+
},
87+
}
88+
89+
configureFlags(cmd)
90+
return cmd
91+
}
92+
93+
func configureFlags(cmd *cobra.Command) {
94+
cmd.Flags().Int64(limitFlag, 0, "Maximum number of entries to list")
95+
cmd.Flags().Var(flags.UUIDFlag(), instanceIdFlag, "Instance ID")
96+
97+
err := flags.MarkFlagsRequired(cmd, instanceIdFlag)
98+
cobra.CheckErr(err)
99+
}
100+
101+
func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) {
102+
globalFlags := globalflags.Parse(p, cmd)
103+
if globalFlags.ProjectId == "" {
104+
return nil, &errors.ProjectIdError{}
105+
}
106+
107+
limit := flags.FlagToInt64Pointer(p, cmd, limitFlag)
108+
if limit != nil && *limit < 1 {
109+
return nil, &errors.FlagValidationError{
110+
Flag: limitFlag,
111+
Details: "must be greater than 0",
112+
}
113+
}
114+
115+
model := inputModel{
116+
GlobalFlagModel: globalFlags,
117+
Limit: limit,
118+
InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag),
119+
}
120+
121+
p.DebugInputModel(model)
122+
return &model, nil
123+
}
124+
125+
func buildRequest(ctx context.Context, model *inputModel, apiClient observability.DefaultAPI) observability.ApiListACLRequest {
126+
req := apiClient.ListACL(ctx, model.InstanceId, model.ProjectId)
127+
return req
128+
}
129+
130+
func outputResult(p *print.Printer, outputFormat, instanceLabel string, acls []string) error {
131+
return p.OutputResult(outputFormat, acls, func() error {
132+
if len(acls) == 0 {
133+
p.Outputf("No ACLs found for instance %q\n", instanceLabel)
134+
return nil
135+
}
136+
table := tables.NewTable()
137+
table.SetHeader("CIDR")
138+
for _, acl := range acls {
139+
table.AddRow(acl)
140+
}
141+
err := table.Display(p)
142+
if err != nil {
143+
return fmt.Errorf("render table: %w", err)
144+
}
145+
146+
return nil
147+
})
148+
}

0 commit comments

Comments
 (0)