diff --git a/action/settings/doc.go b/action/settings/doc.go new file mode 100644 index 00000000..349ff46a --- /dev/null +++ b/action/settings/doc.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 + +// The defined CLI settings actions for Vela. +// +// Usage: +// +// import "github.com/go-vela/cli/action/settings" +package settings diff --git a/action/settings/settings.go b/action/settings/settings.go new file mode 100644 index 00000000..1d56bbd9 --- /dev/null +++ b/action/settings/settings.go @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +// Config represents the configuration necessary +// to perform settings related requests with Vela. +type Config struct { + Action string + Compiler + Queue + RepoAllowlist *[]string + ScheduleAllowlist *[]string + Output string +} + +type Compiler struct { + CloneImage *string + TemplateDepth *int + StarlarkExecLimit *uint64 +} + +type Queue struct { + Routes *[]string +} diff --git a/action/settings/update.go b/action/settings/update.go new file mode 100644 index 00000000..29f1b7b8 --- /dev/null +++ b/action/settings/update.go @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "github.com/sirupsen/logrus" + + "github.com/go-vela/cli/internal/output" + "github.com/go-vela/sdk-go/vela" + "github.com/go-vela/server/api/types/settings" +) + +// Update modifies settings based off the provided configuration. +func (c *Config) Update(client *vela.Client) error { + logrus.Debug("executing update for settings configuration") + + // create the settings object + s := &settings.Platform{ + Queue: &settings.Queue{ + Routes: c.Queue.Routes, + }, + Compiler: &settings.Compiler{ + CloneImage: c.Compiler.CloneImage, + TemplateDepth: c.Compiler.TemplateDepth, + StarlarkExecLimit: c.Compiler.StarlarkExecLimit, + }, + RepoAllowlist: c.RepoAllowlist, + ScheduleAllowlist: c.ScheduleAllowlist, + } + + logrus.Trace("updating settings") + + // send API call to modify settings + s_, _, err := client.Admin.Settings.Update(s) + if err != nil { + return err + } + + // handle the output based off the provided configuration + switch c.Output { + case output.DriverDump: + // output in dump format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Dump + return output.Dump(s_) + case output.DriverJSON: + // output in JSON format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#JSON + return output.JSON(s_) + case output.DriverSpew: + // output in spew format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Spew + return output.Spew(s_) + case output.DriverYAML: + // output in YAML format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#YAML + return output.YAML(s_) + default: + // output in stdout format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Stdout + return output.Stdout(s_) + } +} diff --git a/action/settings/update_test.go b/action/settings/update_test.go new file mode 100644 index 00000000..23e053fe --- /dev/null +++ b/action/settings/update_test.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "net/http/httptest" + "testing" + + "github.com/go-vela/sdk-go/vela" + "github.com/go-vela/server/mock/server" +) + +func TestSettings_Config_Update(t *testing.T) { + // setup test server + s := httptest.NewServer(server.FakeHandler()) + + // create a vela client + client, err := vela.NewClient(s.URL, "vela", nil) + if err != nil { + t.Errorf("unable to create client: %v", err) + } + + // setup tests + tests := []struct { + failure bool + config *Config + }{ + { + failure: false, + config: &Config{ + Action: "update", + Output: "", + }, + }, + { + failure: false, + config: &Config{ + Action: "update", + Output: "dump", + }, + }, + { + failure: false, + config: &Config{ + Action: "update", + Output: "json", + }, + }, + { + failure: false, + config: &Config{ + Action: "update", + Output: "spew", + }, + }, + { + failure: false, + config: &Config{ + Action: "update", + Output: "yaml", + }, + }, + { + failure: true, + config: &Config{ + Action: "update", + Output: "", + }, + }, + } + + // run tests + for _, test := range tests { + err := test.config.Update(client) + + if test.failure { + if err == nil { + t.Errorf("Update should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Update returned err: %v", err) + } + } +} diff --git a/action/settings/validate.go b/action/settings/validate.go new file mode 100644 index 00000000..01124278 --- /dev/null +++ b/action/settings/validate.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "github.com/sirupsen/logrus" +) + +// Validate verifies the configuration provided. +func (c *Config) Validate() error { + logrus.Debug("validating settings configuration") + + return nil +} diff --git a/action/settings/validate_test.go b/action/settings/validate_test.go new file mode 100644 index 00000000..277649f3 --- /dev/null +++ b/action/settings/validate_test.go @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "testing" +) + +func TestSettings_Config_Validate(t *testing.T) { + // setup tests + tests := []struct { + failure bool + config *Config + }{ + { + failure: false, + config: &Config{ + Action: "add", + Output: "", + }, + }, + { + failure: true, + config: &Config{ + Action: "add", + Output: "", + }, + }, + { + failure: false, + config: &Config{ + Action: "add", + Output: "", + }, + }, + { + failure: true, + config: &Config{ + Action: "add", + Output: "", + }, + }, + { + failure: true, + config: &Config{ + Action: "add", + Output: "", + }, + }, + { + failure: false, + config: &Config{ + Action: "view", + Output: "", + }, + }, + { + failure: true, + config: &Config{ + Action: "view", + Output: "", + }, + }, + { + failure: false, + config: &Config{ + Action: "get", + Output: "", + }, + }, + { + failure: false, + config: &Config{ + Action: "update", + Output: "", + }, + }, + { + failure: true, + config: &Config{ + Action: "update", + Output: "", + }, + }, + { + failure: true, + config: &Config{ + Action: "update", + Output: "", + }, + }, + } + + // run tests + for _, test := range tests { + err := test.config.Validate() + + if test.failure { + if err == nil { + t.Errorf("Validate should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Validate returned err: %v", err) + } + } +} diff --git a/action/settings/view.go b/action/settings/view.go new file mode 100644 index 00000000..146f2051 --- /dev/null +++ b/action/settings/view.go @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" + + "github.com/sirupsen/logrus" + + "github.com/go-vela/cli/internal/output" + "github.com/go-vela/sdk-go/vela" +) + +// View inspects settings based off the provided configuration. +func (c *Config) View(client *vela.Client) error { + logrus.Debug("executing view for settings configuration") + + logrus.Trace("inspecting settings") + + response, _, err := client.Admin.Settings.Get() + if err != nil { + return fmt.Errorf("unable to retrieve settings: %w", err) + } + + // handle the output based off the provided configuration + switch c.Output { + case output.DriverDump: + // output in dump format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Dump + return output.Dump(response) + case output.DriverJSON: + // output in JSON format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#JSON + return output.JSON(response) + case output.DriverSpew: + // output in spew format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Spew + return output.Spew(response) + case output.DriverYAML: + // output in YAML format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#YAML + return output.YAML(response) + default: + // output in stdout format + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/output?tab=doc#Stdout + return output.Stdout(response) + } +} diff --git a/action/settings/view_test.go b/action/settings/view_test.go new file mode 100644 index 00000000..6e796afb --- /dev/null +++ b/action/settings/view_test.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "net/http/httptest" + "testing" + + "github.com/go-vela/sdk-go/vela" + "github.com/go-vela/server/mock/server" +) + +func TestSettings_Config_View(t *testing.T) { + // setup test server + s := httptest.NewServer(server.FakeHandler()) + + // create a vela client + client, err := vela.NewClient(s.URL, "vela", nil) + if err != nil { + t.Errorf("unable to create client: %v", err) + } + + // setup tests + tests := []struct { + failure bool + config *Config + }{ + { + failure: false, + config: &Config{ + Action: "view", + Output: "", + }, + }, + { + failure: false, + config: &Config{ + Action: "view", + Output: "dump", + }, + }, + { + failure: false, + config: &Config{ + Action: "view", + Output: "json", + }, + }, + { + failure: false, + config: &Config{ + Action: "view", + Output: "spew", + }, + }, + { + failure: false, + config: &Config{ + Action: "view", + Output: "yaml", + }, + }, + { + failure: false, + config: &Config{ + Action: "view", + Output: "yaml", + }, + }, + } + + // run tests + for _, test := range tests { + err := test.config.View(client) + + if test.failure { + if err == nil { + t.Errorf("View should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("View returned err: %v", err) + } + } +} diff --git a/cmd/vela-cli/update.go b/cmd/vela-cli/update.go index 5c1e76d7..e3630626 100644 --- a/cmd/vela-cli/update.go +++ b/cmd/vela-cli/update.go @@ -9,6 +9,7 @@ import ( "github.com/go-vela/cli/command/repo" "github.com/go-vela/cli/command/schedule" "github.com/go-vela/cli/command/secret" + "github.com/go-vela/cli/command/settings" "github.com/go-vela/cli/command/worker" ) @@ -41,6 +42,11 @@ var updateCmds = &cli.Command{ // https://pkg.go.dev/github.com/go-vela/cli/command/secret?tab=doc#CommandUpdate secret.CommandUpdate, + // add the sub command for modifying settings + // + // https://pkg.go.dev/github.com/go-vela/cli/command/settings?tab=doc#CommandUpdate + settings.CommandUpdate, + // add the sub command for modifying a worker // // https://pkg.go.dev/github.com/go-vela/cli/command/worker?tab=doc#CommandUpdate diff --git a/cmd/vela-cli/view.go b/cmd/vela-cli/view.go index 5414481b..7a831e96 100644 --- a/cmd/vela-cli/view.go +++ b/cmd/vela-cli/view.go @@ -15,6 +15,7 @@ import ( "github.com/go-vela/cli/command/schedule" "github.com/go-vela/cli/command/secret" "github.com/go-vela/cli/command/service" + "github.com/go-vela/cli/command/settings" "github.com/go-vela/cli/command/step" "github.com/go-vela/cli/command/worker" ) @@ -78,6 +79,11 @@ var viewCmds = &cli.Command{ // https://pkg.go.dev/github.com/go-vela/cli/command/service?tab=doc#CommandView service.CommandView, + // add the sub command for viewing settings + // + // https://pkg.go.dev/github.com/go-vela/cli/command/settings?tab=doc#CommandView + settings.CommandView, + // add the sub command for viewing a step // // https://pkg.go.dev/github.com/go-vela/cli/command/step?tab=doc#CommandView diff --git a/command/settings/doc.go b/command/settings/doc.go new file mode 100644 index 00000000..af9fbab2 --- /dev/null +++ b/command/settings/doc.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package settings provides the defined settings CLI command for Vela. +// +// Usage: +// +// import "github.com/go-vela/cli/command/settings" +package settings diff --git a/command/settings/update.go b/command/settings/update.go new file mode 100644 index 00000000..e43ccfb1 --- /dev/null +++ b/command/settings/update.go @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" + + "github.com/urfave/cli/v2" + + "github.com/go-vela/cli/action" + "github.com/go-vela/cli/action/settings" + "github.com/go-vela/cli/internal" + "github.com/go-vela/cli/internal/client" + "github.com/go-vela/sdk-go/vela" +) + +const ( + QueueRouteKey = "queue.routes" + CompilerCloneImageKey = "compiler.clone-image" + CompilerTemplateDepthKey = "compiler.template-depth" + CompilerStarlarkExecLimitKey = "compiler.starlark-exec-limit" + RepoAllowlistKey = "repo-allowlist" + ScheduleAllowlistKey = "schedule-allowlist" +) + +// CommandUpdate defines the command for modifying a settings. +var CommandUpdate = &cli.Command{ + Name: "settings", + Description: "(Platform Admin Only) Use this command to update settings.", + Usage: "Update settings from the provided configuration", + Action: update, + Flags: []cli.Flag{ + + // Queue Flags + + &cli.StringSliceFlag{ + EnvVars: []string{"VELA_QUEUE_ROUTES", "SETTINGS_ROUTES", "QUEUE_ROUTES"}, + Name: QueueRouteKey, + Aliases: []string{"routes", "route", "r"}, + Usage: "route assignment for the queue", + }, + + // Compiler Flags + + &cli.IntFlag{ + EnvVars: []string{"VELA_COMPILER_TEMPLATE_DEPTH", "VELA_TEMPLATE_DEPTH", "TEMPLATE_DEPTH"}, + Name: CompilerTemplateDepthKey, + Aliases: []string{"td"}, + Usage: "max template depth for the compiler", + }, + + &cli.StringFlag{ + EnvVars: []string{"VELA_COMPILER_CLONE_IMAGE", "COMPILER_CLONE_IMAGE"}, + Name: CompilerCloneImageKey, + Aliases: []string{"clone"}, + Usage: "image used to clone the repository for the compiler", + }, + + &cli.IntFlag{ + EnvVars: []string{"VELA_COMPILER_STARLARK_EXEC_LIMIT", "COMPILER_STARLARK_EXEC_LIMIT"}, + Name: CompilerStarlarkExecLimitKey, + Usage: "max starlark execution limit for the compiler", + }, + + // Misc Flags + + &cli.StringSliceFlag{ + EnvVars: []string{"VELA_REPO_ALLOWLIST", "REPO_ALLOWLIST"}, + Name: RepoAllowlistKey, + Aliases: []string{"repos", "ral"}, + Usage: "allowlist of repositories that are permitted to use Vela", + }, + + &cli.StringSliceFlag{ + EnvVars: []string{"VELA_SCHEDULE_ALLOWLIST", "SCHEDULE_ALLOWLIST"}, + Name: ScheduleAllowlistKey, + Aliases: []string{"schedules", "sal"}, + Usage: "allowlist of schedules that are permitted to use Vela", + }, + + // Output Flags + + &cli.StringFlag{ + EnvVars: []string{"VELA_OUTPUT", "SETTINGS_OUTPUT"}, + Name: internal.FlagOutput, + Aliases: []string{"op"}, + Usage: "format the output in json, spew or yaml", + }, + }, + CustomHelpTemplate: fmt.Sprintf(`%s +EXAMPLES: + 1. Update settings to change the compiler template depth to 2. + $ {{.HelpName}} --compiler.template-depth 2 + 2. Update settings with custom queue routes. + $ {{.HelpName}} --queue.route large --queue.route small + +DOCUMENTATION: + + https://go-vela.github.io/docs/reference/cli/settings/update/ +`, cli.CommandHelpTemplate), +} + +// helper function to capture the provided input +// and create the object used to modify settings. +func update(c *cli.Context) error { + // load variables from the config file + err := action.Load(c) + if err != nil { + return err + } + + // parse the Vela client from the context + // + // https://pkg.go.dev/github.com/go-vela/cli/internal/client?tab=doc#Parse + client, err := client.Parse(c) + if err != nil { + return err + } + + // create the settings configuration + s := &settings.Config{ + Queue: settings.Queue{}, + Compiler: settings.Compiler{}, + } + + // queue + if c.IsSet(QueueRouteKey) { + s.Queue.Routes = vela.Strings(c.StringSlice(QueueRouteKey)) + } + + // compiler + if c.IsSet(CompilerCloneImageKey) { + s.Compiler.CloneImage = vela.String(c.String(CompilerCloneImageKey)) + } + + if c.IsSet(CompilerTemplateDepthKey) { + s.Compiler.TemplateDepth = vela.Int(c.Int(CompilerTemplateDepthKey)) + } + + if c.IsSet(CompilerStarlarkExecLimitKey) { + s.Compiler.StarlarkExecLimit = vela.UInt64(c.Uint64(CompilerStarlarkExecLimitKey)) + } + + // misc + if c.IsSet(RepoAllowlistKey) { + s.RepoAllowlist = vela.Strings(c.StringSlice(RepoAllowlistKey)) + } + + if c.IsSet(ScheduleAllowlistKey) { + s.ScheduleAllowlist = vela.Strings(c.StringSlice(ScheduleAllowlistKey)) + } + + // validate settings configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/settings?tab=doc#Config.Validate + err = s.Validate() + if err != nil { + return err + } + + // execute the update call for the settings configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/settings?tab=doc#Config.Update + return s.Update(client) +} diff --git a/command/settings/view.go b/command/settings/view.go new file mode 100644 index 00000000..96a3d7e1 --- /dev/null +++ b/command/settings/view.go @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" + + "github.com/urfave/cli/v2" + + "github.com/go-vela/cli/action" + "github.com/go-vela/cli/action/settings" + "github.com/go-vela/cli/internal" + "github.com/go-vela/cli/internal/client" +) + +// CommandView defines the command for inspecting the platform settings record. +var CommandView = &cli.Command{ + Name: "settings", + Description: "Use this command to view platform settings.", + Usage: "View details for platform settings", + Aliases: []string{"platform"}, + Action: view, + Flags: []cli.Flag{ + + // Output Flags + + &cli.StringFlag{ + EnvVars: []string{"VELA_OUTPUT", "SETTINGS_OUTPUT"}, + Name: internal.FlagOutput, + Aliases: []string{"op"}, + Usage: "format the output in json, spew or yaml", + Value: "yaml", + }, + }, + CustomHelpTemplate: fmt.Sprintf(`%s +EXAMPLES: + 1. View platform settings. + $ {{.HelpName}} + +DOCUMENTATION: + + https://go-vela.github.io/docs/reference/cli/settings/view/ +`, cli.CommandHelpTemplate), +} + +// helper function to capture the provided input +// and create the object used to inspect. +func view(c *cli.Context) error { + // load variables from the config file + err := action.Load(c) + if err != nil { + return err + } + + // parse the Vela client from the context + client, err := client.Parse(c) + if err != nil { + return err + } + + // create the configuration + s := &settings.Config{ + Action: internal.ActionView, + Output: c.String(internal.FlagOutput), + } + + // validate settings configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/settings?tab=doc#Config.Validate + err = s.Validate() + if err != nil { + return err + } + + // execute the view call for the settings configuration + // + // https://pkg.go.dev/github.com/go-vela/cli/action/settings?tab=doc#Config.View + return s.View(client) +}