diff --git a/docs/stackit_argus.md b/docs/stackit_argus.md index eb22ea0fa..ab22866b5 100644 --- a/docs/stackit_argus.md +++ b/docs/stackit_argus.md @@ -31,5 +31,5 @@ stackit argus [flags] * [stackit](./stackit.md) - Manage STACKIT resources using the command line * [stackit argus instance](./stackit_argus_instance.md) - Provides functionality for Argus instances * [stackit argus plans](./stackit_argus_plans.md) - Lists all Argus service plans -* [stackit argus scrape-configs](./stackit_argus_scrape-configs.md) - Provides functionality for scrape configs in Argus. +* [stackit argus scrape-config](./stackit_argus_scrape-config.md) - Provides functionality for scrape configurations in Argus diff --git a/docs/stackit_argus_scrape-config.md b/docs/stackit_argus_scrape-config.md new file mode 100644 index 000000000..42927dd0d --- /dev/null +++ b/docs/stackit_argus_scrape-config.md @@ -0,0 +1,35 @@ +## stackit argus scrape-config + +Provides functionality for scrape configurations in Argus + +### Synopsis + +Provides functionality for scrape configurations in Argus. + +``` +stackit argus scrape-config [flags] +``` + +### Options + +``` + -h, --help Help for "stackit argus scrape-config" +``` + +### 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"] + -p, --project-id string Project ID + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit argus](./stackit_argus.md) - Provides functionality for Argus +* [stackit argus scrape-config create](./stackit_argus_scrape-config_create.md) - Creates a scrape configuration for an Argus instance +* [stackit argus scrape-config delete](./stackit_argus_scrape-config_delete.md) - Deletes a scrape configuration from an Argus instance +* [stackit argus scrape-config generate-payload](./stackit_argus_scrape-config_generate-payload.md) - Generates a payload to create/update scrape configurations for an Argus instance + diff --git a/docs/stackit_argus_scrape-configs_create.md b/docs/stackit_argus_scrape-config_create.md similarity index 55% rename from docs/stackit_argus_scrape-configs_create.md rename to docs/stackit_argus_scrape-config_create.md index 1f52a31bb..9f0f3e13b 100644 --- a/docs/stackit_argus_scrape-configs_create.md +++ b/docs/stackit_argus_scrape-config_create.md @@ -1,42 +1,42 @@ -## stackit argus scrape-configs create +## stackit argus scrape-config create -Creates a Scrape Config job for an Argus instance +Creates a scrape configuration for an Argus instance ### Synopsis -Creates a Scrape Config job for an Argus instance. +Creates a scrape configuration job for an Argus instance. The payload can be provided as a JSON string or a file path prefixed with "@". If no payload is provided, a default payload will be used. See https://docs.api.stackit.cloud/documentation/argus/version/v1#tag/scrape-config/operation/v1_projects_instances_scrapeconfigs_create for information regarding the payload structure. ``` -stackit argus scrape-configs create [flags] +stackit argus scrape-config create [flags] ``` ### Examples ``` - Create a Scrape Config job on Argus instance "xxx" using default configuration - $ stackit argus scrape-configs create + Create a scrape configuration on Argus instance "xxx" using default configuration + $ stackit argus scrape-config create - Create a Scrape Config job on Argus instance "xxx" using an API payload sourced from the file "./payload.json" - $ stackit argus scrape-configs create --payload @./payload.json --instance-id xxx + Create a scrape configuration on Argus instance "xxx" using an API payload sourced from the file "./payload.json" + $ stackit argus scrape-config create --payload @./payload.json --instance-id xxx - Create a Scrape Config job on Argus instance "xxx" using an API payload provided as a JSON string - $ stackit argus scrape-configs create --payload "{...}" --instance-id xxx + Create a scrape configuration on Argus instance "xxx" using an API payload provided as a JSON string + $ stackit argus scrape-config create --payload "{...}" --instance-id xxx Generate a payload with default values, and adapt it with custom values for the different configuration options - $ stackit argus scrape-configs generate-payload > ./payload.json + $ stackit argus scrape-config generate-payload > ./payload.json - $ stackit argus scrape-configs create --payload @./payload.json --instance-id xxx + $ stackit argus scrape-config create --payload @./payload.json --instance-id xxx ``` ### Options ``` - -h, --help Help for "stackit argus scrape-configs create" + -h, --help Help for "stackit argus scrape-config create" --instance-id string Instance ID - --payload string Request payload (JSON). Can be a string or a file path, if prefixed with "@" (example: @./payload.json). If unset, will use a default payload (you can check it by running "stackit argus scrape-configs generate-payload") + --payload string Request payload (JSON). Can be a string or a file path, if prefixed with "@" (example: @./payload.json). If unset, will use a default payload (you can check it by running "stackit argus scrape-config generate-payload") ``` ### Options inherited from parent commands @@ -51,5 +51,5 @@ stackit argus scrape-configs create [flags] ### SEE ALSO -* [stackit argus scrape-configs](./stackit_argus_scrape-configs.md) - Provides functionality for scrape configs in Argus. +* [stackit argus scrape-config](./stackit_argus_scrape-config.md) - Provides functionality for scrape configurations in Argus diff --git a/docs/stackit_argus_scrape-config_delete.md b/docs/stackit_argus_scrape-config_delete.md new file mode 100644 index 000000000..75a2d43d6 --- /dev/null +++ b/docs/stackit_argus_scrape-config_delete.md @@ -0,0 +1,40 @@ +## stackit argus scrape-config delete + +Deletes a scrape configuration from an Argus instance + +### Synopsis + +Deletes a scrape configuration from an Argus instance. + +``` +stackit argus scrape-config delete JOB_NAME [flags] +``` + +### Examples + +``` + Delete a scrape configuration job with name "my-config" from Argus instance "xxx" + $ stackit argus scrape-config delete my-config --instance-id xxx +``` + +### Options + +``` + -h, --help Help for "stackit argus scrape-config delete" + --instance-id string Instance ID +``` + +### 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"] + -p, --project-id string Project ID + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit argus scrape-config](./stackit_argus_scrape-config.md) - Provides functionality for scrape configurations in Argus + diff --git a/docs/stackit_argus_scrape-configs_generate-payload.md b/docs/stackit_argus_scrape-config_generate-payload.md similarity index 66% rename from docs/stackit_argus_scrape-configs_generate-payload.md rename to docs/stackit_argus_scrape-config_generate-payload.md index de814025a..eb2831d23 100644 --- a/docs/stackit_argus_scrape-configs_generate-payload.md +++ b/docs/stackit_argus_scrape-config_generate-payload.md @@ -1,39 +1,39 @@ -## stackit argus scrape-configs generate-payload +## stackit argus scrape-config generate-payload -Generates a payload to create/update Scrape Configurations for an Argus instance +Generates a payload to create/update scrape configurations for an Argus instance ### Synopsis -Generates a JSON payload with values to be used as --payload input for Scrape Configurations creation or update. -This command can be used to generate a payload to update an existing Scrape Config job or to create a new Scrape Config job. -To update an existing Scrape Config job, provide the job name and the instance ID of the Argus instance. -To obtain a default payload to create a new Scrape Config job, run the command with no flags. +Generates a JSON payload with values to be used as --payload input for scrape configurations creation or update. +This command can be used to generate a payload to update an existing scrape config or to create a new scrape config job. +To update an existing scrape config job, provide the job name and the instance ID of the Argus instance. +To obtain a default payload to create a new scrape config job, run the command with no flags. Note that some of the default values provided, such as the job name, the metrics path and URL of the targets, should be adapted to your use case. See https://docs.api.stackit.cloud/documentation/argus/version/v1#tag/scrape-config/operation/v1_projects_instances_scrapeconfigs_create for information regarding the payload structure. ``` -stackit argus scrape-configs generate-payload [flags] +stackit argus scrape-config generate-payload [flags] ``` ### Examples ``` Generate a Create payload with default values, and adapt it with custom values for the different configuration options - $ stackit argus scrape-configs generate-payload > ./payload.json + $ stackit argus scrape-config generate-payload > ./payload.json - $ stackit argus scrape-configs create my-config --payload @./payload.json + $ stackit argus scrape-config create my-config --payload @./payload.json Generate an Update payload with the values of an existing configuration named "my-config" for Argus instance xxx, and adapt it with custom values for the different configuration options - $ stackit argus scrape-configs generate-payload --job-name my-config --instance-id xxx > ./payload.json + $ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx > ./payload.json - $ stackit argus scrape-configs update my-config --payload @./payload.json + $ stackit argus scrape-config update my-config --payload @./payload.json ``` ### Options ``` - -h, --help Help for "stackit argus scrape-configs generate-payload" + -h, --help Help for "stackit argus scrape-config generate-payload" --instance-id string Instance ID -n, --job-name string If set, generates an update payload with the current state of the given scrape config. If unset, generates a create payload with default values ``` @@ -50,5 +50,5 @@ stackit argus scrape-configs generate-payload [flags] ### SEE ALSO -* [stackit argus scrape-configs](./stackit_argus_scrape-configs.md) - Provides functionality for scrape configs in Argus. +* [stackit argus scrape-config](./stackit_argus_scrape-config.md) - Provides functionality for scrape configurations in Argus diff --git a/docs/stackit_argus_scrape-configs.md b/docs/stackit_argus_scrape-configs.md deleted file mode 100644 index b1ab5f10a..000000000 --- a/docs/stackit_argus_scrape-configs.md +++ /dev/null @@ -1,34 +0,0 @@ -## stackit argus scrape-configs - -Provides functionality for scrape configs in Argus. - -### Synopsis - -Provides functionality for scrape configurations in Argus. - -``` -stackit argus scrape-configs [flags] -``` - -### Options - -``` - -h, --help Help for "stackit argus scrape-configs" -``` - -### 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"] - -p, --project-id string Project ID - --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") -``` - -### SEE ALSO - -* [stackit argus](./stackit_argus.md) - Provides functionality for Argus -* [stackit argus scrape-configs create](./stackit_argus_scrape-configs_create.md) - Creates a Scrape Config job for an Argus instance -* [stackit argus scrape-configs generate-payload](./stackit_argus_scrape-configs_generate-payload.md) - Generates a payload to create/update Scrape Configurations for an Argus instance - diff --git a/internal/cmd/argus/argus.go b/internal/cmd/argus/argus.go index 8e93e6c6f..b57fd9fb7 100644 --- a/internal/cmd/argus/argus.go +++ b/internal/cmd/argus/argus.go @@ -3,7 +3,7 @@ package argus import ( "github.com/stackitcloud/stackit-cli/internal/cmd/argus/instance" "github.com/stackitcloud/stackit-cli/internal/cmd/argus/plans" - scrapeconfigs "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-configs" + scrapeconfig "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-config" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -26,5 +26,5 @@ func NewCmd(p *print.Printer) *cobra.Command { func addSubcommands(cmd *cobra.Command, p *print.Printer) { cmd.AddCommand(plans.NewCmd(p)) cmd.AddCommand(instance.NewCmd(p)) - cmd.AddCommand(scrapeconfigs.NewCmd(p)) + cmd.AddCommand(scrapeconfig.NewCmd(p)) } diff --git a/internal/cmd/argus/scrape-configs/create/create.go b/internal/cmd/argus/scrape-config/create/create.go similarity index 78% rename from internal/cmd/argus/scrape-configs/create/create.go rename to internal/cmd/argus/scrape-config/create/create.go index a46b2ac4f..4eeda25d9 100644 --- a/internal/cmd/argus/scrape-configs/create/create.go +++ b/internal/cmd/argus/scrape-config/create/create.go @@ -34,9 +34,9 @@ type inputModel struct { func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "create", - Short: "Creates a Scrape Config job for an Argus instance", + Short: "Creates a scrape configuration for an Argus instance", Long: fmt.Sprintf("%s\n%s\n%s\n%s", - "Creates a Scrape Config job for an Argus instance.", + "Creates a scrape configuration job for an Argus instance.", "The payload can be provided as a JSON string or a file path prefixed with \"@\".", "If no payload is provided, a default payload will be used.", "See https://docs.api.stackit.cloud/documentation/argus/version/v1#tag/scrape-config/operation/v1_projects_instances_scrapeconfigs_create for information regarding the payload structure.", @@ -44,19 +44,19 @@ func NewCmd(p *print.Printer) *cobra.Command { Args: args.NoArgs, Example: examples.Build( examples.NewExample( - `Create a Scrape Config job on Argus instance "xxx" using default configuration`, - "$ stackit argus scrape-configs create"), + `Create a scrape configuration on Argus instance "xxx" using default configuration`, + "$ stackit argus scrape-config create"), examples.NewExample( - `Create a Scrape Config job on Argus instance "xxx" using an API payload sourced from the file "./payload.json"`, - "$ stackit argus scrape-configs create --payload @./payload.json --instance-id xxx"), + `Create a scrape configuration on Argus instance "xxx" using an API payload sourced from the file "./payload.json"`, + "$ stackit argus scrape-config create --payload @./payload.json --instance-id xxx"), examples.NewExample( - `Create a Scrape Config job on Argus instance "xxx" using an API payload provided as a JSON string`, - `$ stackit argus scrape-configs create --payload "{...}" --instance-id xxx`), + `Create a scrape configuration on Argus instance "xxx" using an API payload provided as a JSON string`, + `$ stackit argus scrape-config create --payload "{...}" --instance-id xxx`), examples.NewExample( `Generate a payload with default values, and adapt it with custom values for the different configuration options`, - `$ stackit argus scrape-configs generate-payload > ./payload.json`, + `$ stackit argus scrape-config generate-payload > ./payload.json`, ``, - `$ stackit argus scrape-configs create --payload @./payload.json --instance-id xxx`), + `$ stackit argus scrape-config create --payload @./payload.json --instance-id xxx`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -77,7 +77,7 @@ func NewCmd(p *print.Printer) *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Are you sure you want to create a Scrape Config job on Argus instance %q?", instanceLabel) + prompt := fmt.Sprintf("Are you sure you want to create a scrape configuration on Argus instance %q?", instanceLabel) err = p.PromptForConfirmation(prompt) if err != nil { return err @@ -97,7 +97,7 @@ func NewCmd(p *print.Printer) *cobra.Command { req := buildRequest(ctx, model, apiClient) _, err = req.Execute() if err != nil { - return fmt.Errorf("create Scrape Config job: %w", err) + return fmt.Errorf("create scrape configuration: %w", err) } jobName := model.Payload.JobName @@ -108,7 +108,7 @@ func NewCmd(p *print.Printer) *cobra.Command { s.Start("Creating scrape config") _, err = wait.CreateScrapeConfigWaitHandler(ctx, apiClient, model.InstanceId, *jobName, model.ProjectId).WaitWithContext(ctx) if err != nil { - return fmt.Errorf("wait for Scrape Config job creation: %w", err) + return fmt.Errorf("wait for scrape configuration creation: %w", err) } s.Stop() } @@ -117,7 +117,7 @@ func NewCmd(p *print.Printer) *cobra.Command { if model.Async { operationState = "Triggered creation of" } - p.Outputf("%s Scrape Config job with name %q for Argus instance %q\n", operationState, *jobName, instanceLabel) + p.Outputf("%s scrape configuration with name %q for Argus instance %q\n", operationState, *jobName, instanceLabel) return nil }, } @@ -126,7 +126,7 @@ func NewCmd(p *print.Printer) *cobra.Command { } func configureFlags(cmd *cobra.Command) { - cmd.Flags().Var(flags.ReadFromFileFlag(), payloadFlag, `Request payload (JSON). Can be a string or a file path, if prefixed with "@" (example: @./payload.json). If unset, will use a default payload (you can check it by running "stackit argus scrape-configs generate-payload")`) + cmd.Flags().Var(flags.ReadFromFileFlag(), payloadFlag, `Request payload (JSON). Can be a string or a file path, if prefixed with "@" (example: @./payload.json). If unset, will use a default payload (you can check it by running "stackit argus scrape-config generate-payload")`) cmd.Flags().Var(flags.UUIDFlag(), instanceIdFlag, "Instance ID") err := flags.MarkFlagsRequired(cmd, instanceIdFlag) diff --git a/internal/cmd/argus/scrape-configs/create/create_test.go b/internal/cmd/argus/scrape-config/create/create_test.go similarity index 100% rename from internal/cmd/argus/scrape-configs/create/create_test.go rename to internal/cmd/argus/scrape-config/create/create_test.go diff --git a/internal/cmd/argus/scrape-config/delete/delete.go b/internal/cmd/argus/scrape-config/delete/delete.go new file mode 100644 index 000000000..0e7085f7b --- /dev/null +++ b/internal/cmd/argus/scrape-config/delete/delete.go @@ -0,0 +1,126 @@ +package delete + +import ( + "context" + "fmt" + + "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/argus/client" + argusUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/argus/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/spinner" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-sdk-go/services/argus" + "github.com/stackitcloud/stackit-sdk-go/services/argus/wait" +) + +const ( + jobNameArg = "JOB_NAME" + + instanceIdFlag = "instance-id" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + JobName string + InstanceId string +} + +func NewCmd(p *print.Printer) *cobra.Command { + cmd := &cobra.Command{ + Use: fmt.Sprintf("delete %s", jobNameArg), + Short: "Deletes a scrape configuration from an Argus instance", + Long: "Deletes a scrape configuration from an Argus instance.", + Args: args.SingleArg(jobNameArg, nil), + Example: examples.Build( + examples.NewExample( + `Delete a scrape configuration job with name "my-config" from Argus instance "xxx"`, + "$ stackit argus scrape-config delete my-config --instance-id xxx"), + ), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + model, err := parseInput(cmd, args) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(p) + if err != nil { + return err + } + + instanceLabel, err := argusUtils.GetInstanceName(ctx, apiClient, model.InstanceId, model.ProjectId) + if err != nil { + instanceLabel = model.InstanceId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to delete scrape configuration %q on Argus instance %q? (This cannot be undone)", model.JobName, instanceLabel) + err = p.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + _, err = req.Execute() + if err != nil { + return fmt.Errorf("delete scrape configuration: %w", err) + } + + // Wait for async operation, if async mode not enabled + if !model.Async { + s := spinner.New(p) + s.Start("Deleting scrape config") + _, err = wait.DeleteScrapeConfigWaitHandler(ctx, apiClient, model.InstanceId, model.JobName, model.ProjectId).WaitWithContext(ctx) + if err != nil { + return fmt.Errorf("wait for scrape config deletion: %w", err) + } + s.Stop() + } + + operationState := "Deleted" + if model.Async { + operationState = "Triggered deletion of" + } + p.Info("%s scrape configuration with name %q for Argus instance %q\n", operationState, model.JobName, instanceLabel) + return nil + }, + } + configureFlags(cmd) + return cmd +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), instanceIdFlag, "Instance ID") + + err := flags.MarkFlagsRequired(cmd, instanceIdFlag) + cobra.CheckErr(err) +} + +func parseInput(cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + jobName := inputArgs[0] + + globalFlags := globalflags.Parse(cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + return &inputModel{ + GlobalFlagModel: globalFlags, + JobName: jobName, + InstanceId: flags.FlagToStringValue(cmd, instanceIdFlag), + }, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *argus.APIClient) argus.ApiDeleteScrapeConfigRequest { + req := apiClient.DeleteScrapeConfig(ctx, model.InstanceId, model.JobName, model.ProjectId) + return req +} diff --git a/internal/cmd/argus/scrape-config/delete/delete_test.go b/internal/cmd/argus/scrape-config/delete/delete_test.go new file mode 100644 index 000000000..f6f7ae5b6 --- /dev/null +++ b/internal/cmd/argus/scrape-config/delete/delete_test.go @@ -0,0 +1,233 @@ +package delete + +import ( + "context" + "testing" + + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-sdk-go/services/argus" +) + +var projectIdFlag = globalflags.ProjectIdFlag + +type testCtxKey struct{} + +var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") +var testClient = &argus.APIClient{} +var testProjectId = uuid.NewString() +var testInstanceId = uuid.NewString() +var testJobName = "my-config" + +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testJobName, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + projectIdFlag: testProjectId, + instanceIdFlag: testInstanceId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Verbosity: globalflags.VerbosityDefault, + }, + JobName: testJobName, + InstanceId: testInstanceId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +func fixtureRequest(mods ...func(request *argus.ApiDeleteScrapeConfigRequest)) argus.ApiDeleteScrapeConfigRequest { + request := testClient.DeleteScrapeConfig(testCtx, testInstanceId, testJobName, testProjectId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + argValues []string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no values", + argValues: []string{}, + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "no arg values", + argValues: []string{}, + flagValues: fixtureFlagValues(), + isValid: false, + }, + { + description: "no flag values", + argValues: fixtureArgValues(), + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, projectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[projectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[projectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "instance id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, instanceIdFlag) + }), + isValid: false, + }, + { + description: "instance id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[instanceIdFlag] = "" + }), + isValid: false, + }, + { + description: "instance id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[instanceIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cmd := NewCmd(nil) + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + for flag, value := range tt.flagValues { + err := cmd.Flags().Set(flag, value) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("setting flag --%s=%s: %v", flag, value, err) + } + } + + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating args: %v", err) + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + model, err := parseInput(cmd, tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error parsing flags: %v", err) + } + + if !tt.isValid { + t.Fatalf("did not fail on invalid input") + } + diff := cmp.Diff(model, tt.expectedModel) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + isValid bool + expectedRequest argus.ApiDeleteScrapeConfigRequest + }{ + { + description: "base", + model: fixtureInputModel(), + isValid: true, + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/argus/scrape-configs/generate-payload/generate_payload.go b/internal/cmd/argus/scrape-config/generate-payload/generate_payload.go similarity index 85% rename from internal/cmd/argus/scrape-configs/generate-payload/generate_payload.go rename to internal/cmd/argus/scrape-config/generate-payload/generate_payload.go index d79b27b9b..53d47fc53 100644 --- a/internal/cmd/argus/scrape-configs/generate-payload/generate_payload.go +++ b/internal/cmd/argus/scrape-config/generate-payload/generate_payload.go @@ -31,12 +31,12 @@ type inputModel struct { func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "generate-payload", - Short: "Generates a payload to create/update Scrape Configurations for an Argus instance ", + Short: "Generates a payload to create/update scrape configurations for an Argus instance ", Long: fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n", - "Generates a JSON payload with values to be used as --payload input for Scrape Configurations creation or update.", - "This command can be used to generate a payload to update an existing Scrape Config job or to create a new Scrape Config job.", - "To update an existing Scrape Config job, provide the job name and the instance ID of the Argus instance.", - "To obtain a default payload to create a new Scrape Config job, run the command with no flags.", + "Generates a JSON payload with values to be used as --payload input for scrape configurations creation or update.", + "This command can be used to generate a payload to update an existing scrape config or to create a new scrape config job.", + "To update an existing scrape config job, provide the job name and the instance ID of the Argus instance.", + "To obtain a default payload to create a new scrape config job, run the command with no flags.", "Note that some of the default values provided, such as the job name, the metrics path and URL of the targets, should be adapted to your use case.", "See https://docs.api.stackit.cloud/documentation/argus/version/v1#tag/scrape-config/operation/v1_projects_instances_scrapeconfigs_create for information regarding the payload structure.", ), @@ -44,14 +44,14 @@ func NewCmd(p *print.Printer) *cobra.Command { Example: examples.Build( examples.NewExample( `Generate a Create payload with default values, and adapt it with custom values for the different configuration options`, - `$ stackit argus scrape-configs generate-payload > ./payload.json`, + `$ stackit argus scrape-config generate-payload > ./payload.json`, ``, - `$ stackit argus scrape-configs create my-config --payload @./payload.json`), + `$ stackit argus scrape-config create my-config --payload @./payload.json`), examples.NewExample( `Generate an Update payload with the values of an existing configuration named "my-config" for Argus instance xxx, and adapt it with custom values for the different configuration options`, - `$ stackit argus scrape-configs generate-payload --job-name my-config --instance-id xxx > ./payload.json`, + `$ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx > ./payload.json`, ``, - `$ stackit argus scrape-configs update my-config --payload @./payload.json`), + `$ stackit argus scrape-config update my-config --payload @./payload.json`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -74,7 +74,7 @@ func NewCmd(p *print.Printer) *cobra.Command { req := buildRequest(ctx, model, apiClient) resp, err := req.Execute() if err != nil { - return fmt.Errorf("read Argus Scrape Config: %w", err) + return fmt.Errorf("read Argus scrape config: %w", err) } payload, err := argusUtils.MapToUpdateScrapeConfigPayload(resp) @@ -101,7 +101,7 @@ func parseInput(cmd *cobra.Command) (*inputModel, error) { instanceId := flags.FlagToStringValue(cmd, instanceIdFlag) if jobName != nil && (globalFlags.ProjectId == "" || instanceId == "") { - return nil, fmt.Errorf("if a job-name is provided then instance-id and project-id must to be provided") + return nil, fmt.Errorf("if a job-name is provided then instance-id and project-id must be provided") } return &inputModel{ diff --git a/internal/cmd/argus/scrape-configs/generate-payload/generate_payload_test.go b/internal/cmd/argus/scrape-config/generate-payload/generate_payload_test.go similarity index 100% rename from internal/cmd/argus/scrape-configs/generate-payload/generate_payload_test.go rename to internal/cmd/argus/scrape-config/generate-payload/generate_payload_test.go diff --git a/internal/cmd/argus/scrape-configs/scrape_configs.go b/internal/cmd/argus/scrape-config/scrape_config.go similarity index 71% rename from internal/cmd/argus/scrape-configs/scrape_configs.go rename to internal/cmd/argus/scrape-config/scrape_config.go index 5e01f8028..41517c774 100644 --- a/internal/cmd/argus/scrape-configs/scrape_configs.go +++ b/internal/cmd/argus/scrape-config/scrape_config.go @@ -1,8 +1,9 @@ -package scrapeconfigs +package scrapeconfig import ( - "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-configs/create" - generatepayload "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-configs/generate-payload" + "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-config/create" + "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-config/delete" + generatepayload "github.com/stackitcloud/stackit-cli/internal/cmd/argus/scrape-config/generate-payload" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -12,8 +13,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ - Use: "scrape-configs", - Short: "Provides functionality for scrape configs in Argus.", + Use: "scrape-config", + Short: "Provides functionality for scrape configurations in Argus", Long: "Provides functionality for scrape configurations in Argus.", Args: args.NoArgs, Run: utils.CmdHelp, @@ -25,4 +26,5 @@ func NewCmd(p *print.Printer) *cobra.Command { func addSubcommands(cmd *cobra.Command, p *print.Printer) { cmd.AddCommand(generatepayload.NewCmd(p)) cmd.AddCommand(create.NewCmd(p)) + cmd.AddCommand(delete.NewCmd(p)) }