From 8154cb9662dedbff1ba8bb416821c85f2cd384ff Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Wed, 15 Feb 2023 06:14:26 +1300 Subject: [PATCH 01/15] Adds invoked argument parser --- cmd/helpers.go | 15 ++++++++++++++ cmd/helpers_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/cmd/helpers.go b/cmd/helpers.go index 7176566a..cfb90f7c 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -2,6 +2,7 @@ package cmd import ( "crypto/sha1" + "errors" "fmt" "regexp" "strings" @@ -53,3 +54,17 @@ func flagStringNullValueOrNil(flags *pflag.FlagSet, flag string) (*null.String, // if not defined, return nil return nil, nil } + +func splitInvokeTaskArguments(invokedTaskArguments []string) (map[string]string, error) { + parsedArgs := map[string]string{} + + for _, v := range invokedTaskArguments { + fmt.Println(v) + split := strings.Split(v, "=") + if len(split) != 2 { + return map[string]string{}, errors.New(fmt.Sprintf("Unable to parse `%v`, the form of arguments should be `KEY=VALUE`", v)) + } + parsedArgs[split[0]] = split[1] + } + return parsedArgs, nil +} diff --git a/cmd/helpers_test.go b/cmd/helpers_test.go index 59524a25..f7f9ea75 100644 --- a/cmd/helpers_test.go +++ b/cmd/helpers_test.go @@ -164,3 +164,51 @@ func Test_flagStringNullValueOrNil(t *testing.T) { }) } } + +func Test_splitInvokeTaskArguments(t *testing.T) { + type args struct { + invokedTaskArguments []string + } + tests := []struct { + name string + args args + want map[string]string + wantErr bool + }{ + { + name: "Standard parsing, single argument", + args: args{ + invokedTaskArguments: []string{ + "KEY1=VALUE1", + }, + }, + want: map[string]string{ + "KEY1": "VALUE1", + }, + wantErr: false, + }, + { + name: "Invalid Input, multiple arguments", + args: args{ + invokedTaskArguments: []string{ + "KEY1=VALUE1", + "INVALID_ARGUMENT", + }, + }, + want: map[string]string{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := splitInvokeTaskArguments(tt.args.invokedTaskArguments) + if (err != nil) != tt.wantErr { + t.Errorf("splitInvokeTaskArguments() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("splitInvokeTaskArguments() got = %v, want %v", got, tt.want) + } + }) + } +} From bcc985fb3fb35860027988a0266c1c9735574cdc Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Wed, 15 Feb 2023 07:30:46 +1300 Subject: [PATCH 02/15] Adds task arguments for custom tasks --- cmd/tasks.go | 20 ++++++++++++++------ pkg/lagoon/environments/main.go | 2 +- pkg/lagoon/environments/tasks.go | 22 +++++++++++++++++++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index 3050c95a..4afe317e 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -203,7 +203,13 @@ Direct: os.Exit(1) } - taskResult, err := eClient.InvokeAdvancedTaskDefinition(cmdProjectName, cmdProjectEnvironment, invokedTaskName) + taskArguments, err := splitInvokeTaskArguments(invokedTaskArguments) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + taskResult, err := eClient.InvokeAdvancedTaskDefinition(cmdProjectName, cmdProjectEnvironment, invokedTaskName, taskArguments) handleError(err) var resultMap map[string]interface{} err = json.Unmarshal([]byte(taskResult), &resultMap) @@ -277,15 +283,17 @@ Path: } var ( - taskName string - invokedTaskName string - taskService string - taskCommand string - taskCommandFile string + taskName string + invokedTaskName string + invokedTaskArguments []string + taskService string + taskCommand string + taskCommandFile string ) func init() { invokeDefinedTask.Flags().StringVarP(&invokedTaskName, "name", "N", "", "Name of the task that will be invoked") + invokeDefinedTask.Flags().StringSliceVar(&invokedTaskArguments, "argument", []string{}, "Arguments to be passed to invoked task, of the form NAME=VALUE") runCustomTask.Flags().StringVarP(&taskName, "name", "N", "Custom Task", "Name of the task that will show in the UI (default: Custom Task)") runCustomTask.Flags().StringVarP(&taskService, "service", "S", "cli", "Name of the service (cli, nginx, other) that should run the task (default: cli)") runCustomTask.Flags().StringVarP(&taskCommand, "command", "c", "", "The command to run in the task") diff --git a/pkg/lagoon/environments/main.go b/pkg/lagoon/environments/main.go index 1be98d34..f2e38fce 100644 --- a/pkg/lagoon/environments/main.go +++ b/pkg/lagoon/environments/main.go @@ -33,7 +33,7 @@ type Client interface { AddEnvironmentVariableToEnvironment(string, string, api.EnvVariable) ([]byte, error) DeleteEnvironmentVariableFromEnvironment(string, string, api.EnvVariable) ([]byte, error) PromoteEnvironment(string, string, string) ([]byte, error) - InvokeAdvancedTaskDefinition(string, string, string) ([]byte, error) + InvokeAdvancedTaskDefinition(string, string, string, map[string]string) ([]byte, error) ListInvokableAdvancedTaskDefinitions(string, string) ([]byte, error) } diff --git a/pkg/lagoon/environments/tasks.go b/pkg/lagoon/environments/tasks.go index 2ca2909d..ef903753 100644 --- a/pkg/lagoon/environments/tasks.go +++ b/pkg/lagoon/environments/tasks.go @@ -373,7 +373,7 @@ func (e *Environments) ListInvokableAdvancedTaskDefinitions(projectName string, } // InvokeAdvancedTaskDefinition will attempt to invoke an advanced task definition on an environment -func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environmentName string, advancedTaskName string) ([]byte, error) { +func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environmentName string, advancedTaskName string, taskArguments map[string]string) ([]byte, error) { // get project info from lagoon, we need the project ID for later project := api.Project{ Name: projectName, @@ -417,10 +417,25 @@ func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environm advancedTaskName, projectName, environmentName)) } + //transform any variables to appropriate structre + type AdvancedTaskDefinitionArgumentValueInput struct { + AdvancedTaskDefinitionArgumentName string `json:"advancedTaskDefinitionArgumentName"` + Value string `json:"value"` + } + taskArgumentValues := []AdvancedTaskDefinitionArgumentValueInput{} + for k, v := range taskArguments { + fmt.Println(k + " " + v) + taskArgument := AdvancedTaskDefinitionArgumentValueInput{ + AdvancedTaskDefinitionArgumentName: k, + Value: v, + } + taskArgumentValues = append(taskArgumentValues, taskArgument) + } + // run the query to add the environment variable to lagoon customReq := api.CustomRequest{ - Query: `mutation invokeRegisteredTask ($environment: Int!, $advancedTaskDefinition: Int!) { - invokeRegisteredTask(advancedTaskDefinition: $advancedTaskDefinition, environment: $environment) { + Query: `mutation invokeRegisteredTask ($environment: Int!, $advancedTaskDefinition: Int!, $taskArgumentValues: [AdvancedTaskDefinitionArgumentValueInput]) { + invokeRegisteredTask(advancedTaskDefinition: $advancedTaskDefinition, environment: $environment, argumentValues: $taskArgumentValues) { id name status @@ -429,6 +444,7 @@ func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environm Variables: map[string]interface{}{ "advancedTaskDefinition": taskId, "environment": environmentInfo.ID, + "taskArgumentValues": taskArgumentValues, }, MappedResult: "invokeRegisteredTask", } From 22f826f20ae6866c421d8d7af86f2bd99b7c20c9 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Wed, 15 Feb 2023 07:38:49 +1300 Subject: [PATCH 03/15] Adds short description of invoke task --- cmd/tasks.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index 4afe317e..d6fb20b0 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -190,8 +190,8 @@ var runDrushCacheClear = &cobra.Command{ var invokeDefinedTask = &cobra.Command{ Use: "invoke", Aliases: []string{"i"}, - Short: "", - Long: `Invoke a task registered against an environment + Short: "Invoke a custom task registered against an environment", + Long: `Invoke a custom task registered against an environment The following are supported methods to use Direct: lagoon run invoke -p example -e main -N "advanced task name" From 2c0d30aa6185c99a23bb44250d507b4aac50cc70 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Wed, 15 Feb 2023 07:43:50 +1300 Subject: [PATCH 04/15] Ran make docs --- docs/commands/lagoon_run.md | 2 +- docs/commands/lagoon_run_invoke.md | 9 +++-- internal/lagoon/client/lgraphql/lgraphql.go | 41 ++++++++++----------- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/commands/lagoon_run.md b/docs/commands/lagoon_run.md index 43cf176c..7ee006e7 100644 --- a/docs/commands/lagoon_run.md +++ b/docs/commands/lagoon_run.md @@ -37,5 +37,5 @@ Run a task against an environment * [lagoon run drush-archivedump](lagoon_run_drush-archivedump.md) - Run a drush archive dump on an environment * [lagoon run drush-cacheclear](lagoon_run_drush-cacheclear.md) - Run a drush cache clear on an environment * [lagoon run drush-sqldump](lagoon_run_drush-sqldump.md) - Run a drush sql dump on an environment -* [lagoon run invoke](lagoon_run_invoke.md) - +* [lagoon run invoke](lagoon_run_invoke.md) - Invoke a custom task registered against an environment diff --git a/docs/commands/lagoon_run_invoke.md b/docs/commands/lagoon_run_invoke.md index c41ced3d..46830a66 100644 --- a/docs/commands/lagoon_run_invoke.md +++ b/docs/commands/lagoon_run_invoke.md @@ -1,10 +1,10 @@ ## lagoon run invoke - +Invoke a custom task registered against an environment ### Synopsis -Invoke a task registered against an environment +Invoke a custom task registered against an environment The following are supported methods to use Direct: lagoon run invoke -p example -e main -N "advanced task name" @@ -17,8 +17,9 @@ lagoon run invoke [flags] ### Options ``` - -h, --help help for invoke - -N, --name string Name of the task that will be invoked + --argument strings Arguments to be passed to invoked task, of the form NAME=VALUE + -h, --help help for invoke + -N, --name string Name of the task that will be invoked ``` ### Options inherited from parent commands diff --git a/internal/lagoon/client/lgraphql/lgraphql.go b/internal/lagoon/client/lgraphql/lgraphql.go index 085f2de6..595da684 100644 --- a/internal/lagoon/client/lgraphql/lgraphql.go +++ b/internal/lagoon/client/lgraphql/lgraphql.go @@ -1,6 +1,5 @@ -// Code generated by go-bindata. (@generated) DO NOT EDIT. - -// Package lgraphql generated by go-bindata.// sources: +// Code generated for package lgraphql by go-bindata DO NOT EDIT. (@generated) +// sources: // _lgraphql/addDeployTarget.graphql // _lgraphql/addDeployTargetConfig.graphql // _lgraphql/addEnvVariable.graphql @@ -60,7 +59,7 @@ import ( func bindataRead(data []byte, name string) ([]byte, error) { gz, err := gzip.NewReader(bytes.NewBuffer(data)) if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) + return nil, fmt.Errorf("Read %q: %v", name, err) } var buf bytes.Buffer @@ -68,7 +67,7 @@ func bindataRead(data []byte, name string) ([]byte, error) { clErr := gz.Close() if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) + return nil, fmt.Errorf("Read %q: %v", name, err) } if clErr != nil { return nil, err @@ -104,7 +103,7 @@ func (fi bindataFileInfo) Mode() os.FileMode { return fi.mode } -// ModTime return file modify time +// Mode return file modify time func (fi bindataFileInfo) ModTime() time.Time { return fi.modTime } @@ -963,8 +962,8 @@ func _lgraphqlVariablesGetenvvariablesbyprojectenvironmentnameGraphql() (*asset, // It returns an error if the asset could not be found or // could not be loaded. func Asset(name string) ([]byte, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) @@ -989,8 +988,8 @@ func MustAsset(name string) []byte { // It returns an error if the asset could not be found or // could not be loaded. func AssetInfo(name string) (os.FileInfo, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) @@ -1059,22 +1058,20 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("nonexistent") would return an error +// AssetDir("foo.txt") and AssetDir("notexist") would return an error // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree if len(name) != 0 { - canonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(canonicalName, "/") + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") for _, p := range pathList { node = node.Children[p] if node == nil { @@ -1189,6 +1186,6 @@ func RestoreAssets(dir, name string) error { } func _filePath(dir, name string) string { - canonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } From 37d83bc6c7c494c4fdfc155ba6caa7dddf9e912b Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Thu, 16 Feb 2023 07:57:33 +1300 Subject: [PATCH 05/15] Removes debug prints --- cmd/helpers.go | 1 - cmd/tasks.go | 2 +- docs/commands/lagoon_run_invoke.md | 2 +- pkg/lagoon/environments/tasks.go | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/helpers.go b/cmd/helpers.go index cfb90f7c..f4287392 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -59,7 +59,6 @@ func splitInvokeTaskArguments(invokedTaskArguments []string) (map[string]string, parsedArgs := map[string]string{} for _, v := range invokedTaskArguments { - fmt.Println(v) split := strings.Split(v, "=") if len(split) != 2 { return map[string]string{}, errors.New(fmt.Sprintf("Unable to parse `%v`, the form of arguments should be `KEY=VALUE`", v)) diff --git a/cmd/tasks.go b/cmd/tasks.go index d6fb20b0..8c09b2ee 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -194,7 +194,7 @@ var invokeDefinedTask = &cobra.Command{ Long: `Invoke a custom task registered against an environment The following are supported methods to use Direct: - lagoon run invoke -p example -e main -N "advanced task name" + lagoon run invoke -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] `, Run: func(cmd *cobra.Command, args []string) { if cmdProjectName == "" || cmdProjectEnvironment == "" || invokedTaskName == "" { diff --git a/docs/commands/lagoon_run_invoke.md b/docs/commands/lagoon_run_invoke.md index 46830a66..d1cc69e3 100644 --- a/docs/commands/lagoon_run_invoke.md +++ b/docs/commands/lagoon_run_invoke.md @@ -7,7 +7,7 @@ Invoke a custom task registered against an environment Invoke a custom task registered against an environment The following are supported methods to use Direct: - lagoon run invoke -p example -e main -N "advanced task name" + lagoon run invoke -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] ``` diff --git a/pkg/lagoon/environments/tasks.go b/pkg/lagoon/environments/tasks.go index ef903753..f5e73ce3 100644 --- a/pkg/lagoon/environments/tasks.go +++ b/pkg/lagoon/environments/tasks.go @@ -424,7 +424,6 @@ func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environm } taskArgumentValues := []AdvancedTaskDefinitionArgumentValueInput{} for k, v := range taskArguments { - fmt.Println(k + " " + v) taskArgument := AdvancedTaskDefinitionArgumentValueInput{ AdvancedTaskDefinitionArgumentName: k, Value: v, From c302f3e1817261725d0c0ed13725a747753445e0 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Feb 2023 15:47:07 +1300 Subject: [PATCH 06/15] Adds first pass at interactive invocation --- cmd/tasks.go | 116 ++++++++++++++++++ ...vironmentAndTasksByEnvironmentName.graphql | 45 +++++++ internal/lagoon/client/lgraphql/lgraphql.go | 101 +++++++++------ internal/lagoon/client/query.go | 21 ++++ internal/lagoon/tasks.go | 6 + internal/schema/environment.go | 26 +++- 6 files changed, 271 insertions(+), 44 deletions(-) create mode 100644 internal/lagoon/client/_lgraphql/environmentAndTasksByEnvironmentName.graphql diff --git a/cmd/tasks.go b/cmd/tasks.go index 8c09b2ee..b7c5a225 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/manifoldco/promptui" "github.com/spf13/cobra" "github.com/uselagoon/lagoon-cli/internal/lagoon" "github.com/uselagoon/lagoon-cli/internal/lagoon/client" @@ -222,6 +223,119 @@ Direct: }, } +var invokeInteractiveTask = &cobra.Command{ + Use: "interactive", + Aliases: []string{"i"}, + Short: "Interactively run a custom task against an environment", + Long: `Interactively run a custom task against an environment +Provides prompts for arguments +example: + lagoon run invoke interactive -p example -e main +`, + Run: func(cmd *cobra.Command, args []string) { + debug, err := cmd.Flags().GetBool("debug") + if cmdProjectName == "" || cmdProjectEnvironment == "" { + fmt.Println("Missing arguments: Project name or environment name are not defined") + cmd.Help() + os.Exit(1) + } + + //TODO: get project id for subsequent queries + current := lagoonCLIConfig.Current + lc := client.New( + lagoonCLIConfig.Lagoons[current].GraphQL, + lagoonCLIConfig.Lagoons[current].Token, + lagoonCLIConfig.Lagoons[current].Version, + lagoonCLIVersion, + debug) + project, err := lagoon.GetMinimalProjectByName(context.TODO(), cmdProjectName, lc) + if err != nil { + fmt.Println(err.Error()) + return + } + + //TODO: get list of tasks and their arguments + + environment, err := lagoon.TasksForEnvironment(context.TODO(), project.ID, cmdProjectEnvironment, lc) + + if err != nil { + fmt.Println(err.Error()) + return + } + + if len(environment.AdvancedTasks) == 0 { + fmt.Println("No custom tasks registered against environment - exiting") + return + } + + prompt := promptui.Select{ + Label: "Select Task", + Items: environment.AdvancedTasks, + Templates: &promptui.SelectTemplates{ + Active: "\U0001F336 {{ .Name }}", + Inactive: " {{ .Name }}", + Selected: "\U0001F336 {{ .Name | red | cyan }}", + Details: `{{ .Name }} -- {{ .Description }}`, + }, + } + + taskIndex, _, err := prompt.Run() + + if err != nil { + fmt.Printf("Prompt failed %v\n", err) + return + } + + //TODO: fill out any arguments + task := environment.AdvancedTasks[taskIndex] + taskArguments := map[string]string{} + taskArgumentString := "" + for _, v := range task.AdvancedTaskDefinitionArguments { + if len(v.Range) != 0 { //we have a selection + prompt = promptui.Select{ + Label: v.DisplayName, + Items: v.Range, + } + _, argumentValue, err := prompt.Run() + if err != nil { + fmt.Printf("Prompt failed %v\n", err) + return + } + taskArguments[v.Name] = argumentValue + taskArgumentString = taskArgumentString + fmt.Sprintf("%v(%v) : %v", v.DisplayName, v.Name, argumentValue) + } else { // standard prompt + prompt := promptui.Prompt{ + Label: fmt.Sprintf("%v", v.DisplayName), + } + argumentValue, err := prompt.Run() + + if err != nil { + fmt.Printf("Prompt failed %v\n", err) + return + } + taskArguments[v.Name] = argumentValue + taskArgumentString = taskArgumentString + fmt.Sprintf(", %v(%v) : %v", v.DisplayName, v.Name, argumentValue) + } + } + + if !yesNo(fmt.Sprintf("Run command `%v` with arguments %v", task.Name, taskArgumentString)) { + fmt.Println("Exiting") + return + } + + taskResult, err := eClient.InvokeAdvancedTaskDefinition(cmdProjectName, cmdProjectEnvironment, task.Name, taskArguments) + handleError(err) + var resultMap map[string]interface{} + err = json.Unmarshal([]byte(taskResult), &resultMap) + handleError(err) + resultData := output.Result{ + Result: "success", + ResultData: resultMap, + } + output.RenderResult(resultData, outputOptions) + }, +} + var runCustomTask = &cobra.Command{ Use: "custom", Aliases: []string{"c"}, @@ -292,6 +406,8 @@ var ( ) func init() { + //register sub tasks + invokeDefinedTask.AddCommand(invokeInteractiveTask) invokeDefinedTask.Flags().StringVarP(&invokedTaskName, "name", "N", "", "Name of the task that will be invoked") invokeDefinedTask.Flags().StringSliceVar(&invokedTaskArguments, "argument", []string{}, "Arguments to be passed to invoked task, of the form NAME=VALUE") runCustomTask.Flags().StringVarP(&taskName, "name", "N", "Custom Task", "Name of the task that will show in the UI (default: Custom Task)") diff --git a/internal/lagoon/client/_lgraphql/environmentAndTasksByEnvironmentName.graphql b/internal/lagoon/client/_lgraphql/environmentAndTasksByEnvironmentName.graphql new file mode 100644 index 00000000..217bdcd8 --- /dev/null +++ b/internal/lagoon/client/_lgraphql/environmentAndTasksByEnvironmentName.graphql @@ -0,0 +1,45 @@ +query ( + $name: String!, + $project: Int!) { + environmentByName( + name: $name, + project: $project) + { + id + name + route + routes + deployType + environmentType + openshiftProjectName + updated + created + deleted + advancedTasks { + ... on AdvancedTaskDefinitionImage { + id + name + description + advancedTaskDefinitionArguments { + id + displayName + name + type + range + } + } + ... on AdvancedTaskDefinitionCommand { + id + name + description + advancedTaskDefinitionArguments { + id + displayName + name + type + range + } + } + } + } + } diff --git a/internal/lagoon/client/lgraphql/lgraphql.go b/internal/lagoon/client/lgraphql/lgraphql.go index 595da684..eb6cb04d 100644 --- a/internal/lagoon/client/lgraphql/lgraphql.go +++ b/internal/lagoon/client/lgraphql/lgraphql.go @@ -24,6 +24,7 @@ // _lgraphql/deployEnvironmentPromote.graphql // _lgraphql/deployEnvironmentPullrequest.graphql // _lgraphql/deployTargetConfigsByProjectId.graphql +// _lgraphql/environmentAndTasksByEnvironmentName.graphql // _lgraphql/environmentByName.graphql // _lgraphql/lagoonSchema.graphql // _lgraphql/lagoonVersion.graphql @@ -598,6 +599,26 @@ func _lgraphqlDeploytargetconfigsbyprojectidGraphql() (*asset, error) { return a, nil } +var __lgraphqlEnvironmentandtasksbyenvironmentnameGraphql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x50\x4b\x6e\xc3\x20\x10\xdd\xfb\x14\x13\xa9\x8b\x44\x8a\x7c\x80\xec\xd2\x76\x93\x8d\x55\xa9\xb9\xc0\xc8\x4c\x5c\x5a\x33\x50\xc0\x91\x50\x94\xbb\x57\xf8\x17\xfc\x69\x2f\xd0\xd9\xc0\x7b\x30\xf3\xde\x9b\xef\x86\x6c\x80\x6d\x06\xf0\xc4\xa8\xe8\x00\xef\xde\x4a\xae\x36\xfb\xc8\x18\xab\x3f\xa9\xf4\x07\x38\xb1\xdf\xec\xe0\x96\x01\x00\x10\x5f\xa5\xd5\xac\x88\xfd\x73\x28\x50\xd1\xb6\xa5\x01\xba\xfe\x76\xcc\xbe\xa7\xc6\x01\xc3\xa8\x5d\xff\x70\xeb\x4f\x00\x29\xc6\x6b\xec\x1c\x81\xd5\x8d\x9f\x21\x37\x42\x41\xa6\xd6\xe1\x1c\xcc\xe3\x47\x62\x6b\xc2\x6b\x43\xec\x3e\xe4\xc5\xbf\x75\x0e\x8a\x54\xa4\x31\x02\x3d\x3d\x1c\x94\x96\x26\x58\x50\x4d\x29\x46\x71\x45\x2e\x49\x9c\xd1\x7d\xb9\x24\x44\xac\x3c\xcf\x41\x33\x1c\x93\x2f\xaf\x74\x91\x2c\xbd\xd4\x7c\x52\x58\xd1\xac\x21\x49\xbe\x48\xdf\x89\xbb\xd2\x4a\x13\xdb\x27\x3c\xae\x2a\x1c\x6d\xd5\xc4\xf0\x73\x5b\x2b\x4a\xed\x70\xe9\x4c\x8d\xa1\x98\x8b\xae\x3a\x89\xe5\xd3\xa5\x0e\x65\x91\xab\x25\x7b\xcf\x7e\x47\x7f\x6e\xe9\x45\x2b\x85\x2c\xfe\xfb\x9e\x86\x5b\x3c\xef\xd9\x4f\x00\x00\x00\xff\xff\x6d\x2d\x35\x63\xa2\x03\x00\x00") + +func _lgraphqlEnvironmentandtasksbyenvironmentnameGraphqlBytes() ([]byte, error) { + return bindataRead( + __lgraphqlEnvironmentandtasksbyenvironmentnameGraphql, + "_lgraphql/environmentAndTasksByEnvironmentName.graphql", + ) +} + +func _lgraphqlEnvironmentandtasksbyenvironmentnameGraphql() (*asset, error) { + bytes, err := _lgraphqlEnvironmentandtasksbyenvironmentnameGraphqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "_lgraphql/environmentAndTasksByEnvironmentName.graphql", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var __lgraphqlEnvironmentbynameGraphql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8e\x4d\x0e\x82\x30\x10\x85\xf7\x9c\xe2\x91\xb8\x80\x84\x13\xb0\x74\xe7\x86\x98\xe8\x05\x08\x1d\xb5\x06\xa6\xb5\x0c\x26\x0d\xf1\xee\x86\x1f\x5b\x70\xd1\xb4\xdf\xd7\xce\xeb\x7b\x0d\xe4\x3c\xb2\x04\x38\x70\xdd\x51\x89\x8b\x38\xcd\xf7\xb4\x98\x8c\x75\xe6\x49\x8d\x94\x38\xb1\xa4\x39\xc6\x04\x00\x88\xdf\xda\x19\xee\x88\xe5\xe8\xab\xba\xa3\x6c\xd6\xc0\x32\x3f\xc7\x14\xab\x0a\x01\xbf\xa8\x7c\xbd\x18\xd7\x1d\xd0\x2a\x1c\xa7\xc9\x00\xce\x0c\xf2\x47\x7d\x40\x45\xb6\x35\xfe\xea\x6d\x7c\xb1\xa9\xb5\xf3\xc6\x12\xf7\x0f\x7d\x93\xf3\xd2\xa0\xda\x7e\x32\x58\x55\x0b\xc5\x06\x8d\xa3\x1d\x2b\x6a\x29\xf2\x27\x99\xd6\x37\x00\x00\xff\xff\xd5\xce\x35\x6e\x32\x01\x00\x00") func _lgraphqlEnvironmentbynameGraphqlBytes() ([]byte, error) { @@ -1034,6 +1055,7 @@ var _bindata = map[string]func() (*asset, error){ "_lgraphql/deployEnvironmentPromote.graphql": _lgraphqlDeployenvironmentpromoteGraphql, "_lgraphql/deployEnvironmentPullrequest.graphql": _lgraphqlDeployenvironmentpullrequestGraphql, "_lgraphql/deployTargetConfigsByProjectId.graphql": _lgraphqlDeploytargetconfigsbyprojectidGraphql, + "_lgraphql/environmentAndTasksByEnvironmentName.graphql": _lgraphqlEnvironmentandtasksbyenvironmentnameGraphql, "_lgraphql/environmentByName.graphql": _lgraphqlEnvironmentbynameGraphql, "_lgraphql/lagoonSchema.graphql": _lgraphqlLagoonschemaGraphql, "_lgraphql/lagoonVersion.graphql": _lgraphqlLagoonversionGraphql, @@ -1096,45 +1118,46 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "_lgraphql": &bintree{nil, map[string]*bintree{ - "addDeployTarget.graphql": &bintree{_lgraphqlAdddeploytargetGraphql, map[string]*bintree{}}, - "addDeployTargetConfig.graphql": &bintree{_lgraphqlAdddeploytargetconfigGraphql, map[string]*bintree{}}, - "addEnvVariable.graphql": &bintree{_lgraphqlAddenvvariableGraphql, map[string]*bintree{}}, - "addGroup.graphql": &bintree{_lgraphqlAddgroupGraphql, map[string]*bintree{}}, - "addGroupsToProject.graphql": &bintree{_lgraphqlAddgroupstoprojectGraphql, map[string]*bintree{}}, - "addNotificationEmail.graphql": &bintree{_lgraphqlAddnotificationemailGraphql, map[string]*bintree{}}, - "addNotificationMicrosoftTeams.graphql": &bintree{_lgraphqlAddnotificationmicrosoftteamsGraphql, map[string]*bintree{}}, - "addNotificationRocketChat.graphql": &bintree{_lgraphqlAddnotificationrocketchatGraphql, map[string]*bintree{}}, - "addNotificationSlack.graphql": &bintree{_lgraphqlAddnotificationslackGraphql, map[string]*bintree{}}, - "addNotificationToProject.graphql": &bintree{_lgraphqlAddnotificationtoprojectGraphql, map[string]*bintree{}}, - "addOrUpdateEnvironment.graphql": &bintree{_lgraphqlAddorupdateenvironmentGraphql, map[string]*bintree{}}, - "addProject.graphql": &bintree{_lgraphqlAddprojectGraphql, map[string]*bintree{}}, - "addRestore.graphql": &bintree{_lgraphqlAddrestoreGraphql, map[string]*bintree{}}, - "addSshKey.graphql": &bintree{_lgraphqlAddsshkeyGraphql, map[string]*bintree{}}, - "addUser.graphql": &bintree{_lgraphqlAdduserGraphql, map[string]*bintree{}}, - "addUserToGroup.graphql": &bintree{_lgraphqlAddusertogroupGraphql, map[string]*bintree{}}, - "backupsForEnvironmentByName.graphql": &bintree{_lgraphqlBackupsforenvironmentbynameGraphql, map[string]*bintree{}}, - "deleteDeployTarget.graphql": &bintree{_lgraphqlDeletedeploytargetGraphql, map[string]*bintree{}}, - "deleteDeployTargetConfig.graphql": &bintree{_lgraphqlDeletedeploytargetconfigGraphql, map[string]*bintree{}}, - "deployEnvironmentBranch.graphql": &bintree{_lgraphqlDeployenvironmentbranchGraphql, map[string]*bintree{}}, - "deployEnvironmentLatest.graphql": &bintree{_lgraphqlDeployenvironmentlatestGraphql, map[string]*bintree{}}, - "deployEnvironmentPromote.graphql": &bintree{_lgraphqlDeployenvironmentpromoteGraphql, map[string]*bintree{}}, - "deployEnvironmentPullrequest.graphql": &bintree{_lgraphqlDeployenvironmentpullrequestGraphql, map[string]*bintree{}}, - "deployTargetConfigsByProjectId.graphql": &bintree{_lgraphqlDeploytargetconfigsbyprojectidGraphql, map[string]*bintree{}}, - "environmentByName.graphql": &bintree{_lgraphqlEnvironmentbynameGraphql, map[string]*bintree{}}, - "lagoonSchema.graphql": &bintree{_lgraphqlLagoonschemaGraphql, map[string]*bintree{}}, - "lagoonVersion.graphql": &bintree{_lgraphqlLagoonversionGraphql, map[string]*bintree{}}, - "listDeployTargets.graphql": &bintree{_lgraphqlListdeploytargetsGraphql, map[string]*bintree{}}, - "me.graphql": &bintree{_lgraphqlMeGraphql, map[string]*bintree{}}, - "minimalProjectByName.graphql": &bintree{_lgraphqlMinimalprojectbynameGraphql, map[string]*bintree{}}, - "projectByName.graphql": &bintree{_lgraphqlProjectbynameGraphql, map[string]*bintree{}}, - "projectByNameMetadata.graphql": &bintree{_lgraphqlProjectbynamemetadataGraphql, map[string]*bintree{}}, - "projectsByMetadata.graphql": &bintree{_lgraphqlProjectsbymetadataGraphql, map[string]*bintree{}}, - "removeProjectMetadataByKey.graphql": &bintree{_lgraphqlRemoveprojectmetadatabykeyGraphql, map[string]*bintree{}}, - "switchActiveStandby.graphql": &bintree{_lgraphqlSwitchactivestandbyGraphql, map[string]*bintree{}}, - "taskByID.graphql": &bintree{_lgraphqlTaskbyidGraphql, map[string]*bintree{}}, - "updateDeployTarget.graphql": &bintree{_lgraphqlUpdatedeploytargetGraphql, map[string]*bintree{}}, - "updateDeployTargetConfig.graphql": &bintree{_lgraphqlUpdatedeploytargetconfigGraphql, map[string]*bintree{}}, - "updateProjectMetadata.graphql": &bintree{_lgraphqlUpdateprojectmetadataGraphql, map[string]*bintree{}}, + "addDeployTarget.graphql": &bintree{_lgraphqlAdddeploytargetGraphql, map[string]*bintree{}}, + "addDeployTargetConfig.graphql": &bintree{_lgraphqlAdddeploytargetconfigGraphql, map[string]*bintree{}}, + "addEnvVariable.graphql": &bintree{_lgraphqlAddenvvariableGraphql, map[string]*bintree{}}, + "addGroup.graphql": &bintree{_lgraphqlAddgroupGraphql, map[string]*bintree{}}, + "addGroupsToProject.graphql": &bintree{_lgraphqlAddgroupstoprojectGraphql, map[string]*bintree{}}, + "addNotificationEmail.graphql": &bintree{_lgraphqlAddnotificationemailGraphql, map[string]*bintree{}}, + "addNotificationMicrosoftTeams.graphql": &bintree{_lgraphqlAddnotificationmicrosoftteamsGraphql, map[string]*bintree{}}, + "addNotificationRocketChat.graphql": &bintree{_lgraphqlAddnotificationrocketchatGraphql, map[string]*bintree{}}, + "addNotificationSlack.graphql": &bintree{_lgraphqlAddnotificationslackGraphql, map[string]*bintree{}}, + "addNotificationToProject.graphql": &bintree{_lgraphqlAddnotificationtoprojectGraphql, map[string]*bintree{}}, + "addOrUpdateEnvironment.graphql": &bintree{_lgraphqlAddorupdateenvironmentGraphql, map[string]*bintree{}}, + "addProject.graphql": &bintree{_lgraphqlAddprojectGraphql, map[string]*bintree{}}, + "addRestore.graphql": &bintree{_lgraphqlAddrestoreGraphql, map[string]*bintree{}}, + "addSshKey.graphql": &bintree{_lgraphqlAddsshkeyGraphql, map[string]*bintree{}}, + "addUser.graphql": &bintree{_lgraphqlAdduserGraphql, map[string]*bintree{}}, + "addUserToGroup.graphql": &bintree{_lgraphqlAddusertogroupGraphql, map[string]*bintree{}}, + "backupsForEnvironmentByName.graphql": &bintree{_lgraphqlBackupsforenvironmentbynameGraphql, map[string]*bintree{}}, + "deleteDeployTarget.graphql": &bintree{_lgraphqlDeletedeploytargetGraphql, map[string]*bintree{}}, + "deleteDeployTargetConfig.graphql": &bintree{_lgraphqlDeletedeploytargetconfigGraphql, map[string]*bintree{}}, + "deployEnvironmentBranch.graphql": &bintree{_lgraphqlDeployenvironmentbranchGraphql, map[string]*bintree{}}, + "deployEnvironmentLatest.graphql": &bintree{_lgraphqlDeployenvironmentlatestGraphql, map[string]*bintree{}}, + "deployEnvironmentPromote.graphql": &bintree{_lgraphqlDeployenvironmentpromoteGraphql, map[string]*bintree{}}, + "deployEnvironmentPullrequest.graphql": &bintree{_lgraphqlDeployenvironmentpullrequestGraphql, map[string]*bintree{}}, + "deployTargetConfigsByProjectId.graphql": &bintree{_lgraphqlDeploytargetconfigsbyprojectidGraphql, map[string]*bintree{}}, + "environmentAndTasksByEnvironmentName.graphql": &bintree{_lgraphqlEnvironmentandtasksbyenvironmentnameGraphql, map[string]*bintree{}}, + "environmentByName.graphql": &bintree{_lgraphqlEnvironmentbynameGraphql, map[string]*bintree{}}, + "lagoonSchema.graphql": &bintree{_lgraphqlLagoonschemaGraphql, map[string]*bintree{}}, + "lagoonVersion.graphql": &bintree{_lgraphqlLagoonversionGraphql, map[string]*bintree{}}, + "listDeployTargets.graphql": &bintree{_lgraphqlListdeploytargetsGraphql, map[string]*bintree{}}, + "me.graphql": &bintree{_lgraphqlMeGraphql, map[string]*bintree{}}, + "minimalProjectByName.graphql": &bintree{_lgraphqlMinimalprojectbynameGraphql, map[string]*bintree{}}, + "projectByName.graphql": &bintree{_lgraphqlProjectbynameGraphql, map[string]*bintree{}}, + "projectByNameMetadata.graphql": &bintree{_lgraphqlProjectbynamemetadataGraphql, map[string]*bintree{}}, + "projectsByMetadata.graphql": &bintree{_lgraphqlProjectsbymetadataGraphql, map[string]*bintree{}}, + "removeProjectMetadataByKey.graphql": &bintree{_lgraphqlRemoveprojectmetadatabykeyGraphql, map[string]*bintree{}}, + "switchActiveStandby.graphql": &bintree{_lgraphqlSwitchactivestandbyGraphql, map[string]*bintree{}}, + "taskByID.graphql": &bintree{_lgraphqlTaskbyidGraphql, map[string]*bintree{}}, + "updateDeployTarget.graphql": &bintree{_lgraphqlUpdatedeploytargetGraphql, map[string]*bintree{}}, + "updateDeployTargetConfig.graphql": &bintree{_lgraphqlUpdatedeploytargetconfigGraphql, map[string]*bintree{}}, + "updateProjectMetadata.graphql": &bintree{_lgraphqlUpdateprojectmetadataGraphql, map[string]*bintree{}}, "variables": &bintree{nil, map[string]*bintree{ "addOrUpdateEnvVariableByName.graphql": &bintree{_lgraphqlVariablesAddorupdateenvvariablebynameGraphql, map[string]*bintree{}}, "deleteEnvVariableByName.graphql": &bintree{_lgraphqlVariablesDeleteenvvariablebynameGraphql, map[string]*bintree{}}, diff --git a/internal/lagoon/client/query.go b/internal/lagoon/client/query.go index eced69a2..4b200f4c 100644 --- a/internal/lagoon/client/query.go +++ b/internal/lagoon/client/query.go @@ -65,6 +65,27 @@ func (c *Client) EnvironmentByName(ctx context.Context, name string, }) } +// EnvironmentByName queries the Lagoon API for an environment by its name and +// parent projectID, and unmarshals the response into environment. +func (c *Client) EnvironmentAndTasksByEnvironmentName(ctx context.Context, name string, + projectID uint, environment *schema.Environment) error { + + req, err := c.newRequest("_lgraphql/environmentAndTasksByEnvironmentName.graphql", + map[string]interface{}{ + "name": name, + "project": projectID, + }) + if err != nil { + return err + } + + return c.client.Run(ctx, req, &struct { + Response *schema.Environment `json:"environmentByName"` + }{ + Response: environment, + }) +} + // BackupsForEnvironmentByName queries the Lagoon API for an environment by its name and // parent projectID, and unmarshals the response into environment. func (c *Client) BackupsForEnvironmentByName(ctx context.Context, name string, diff --git a/internal/lagoon/tasks.go b/internal/lagoon/tasks.go index cce1a113..8631e58f 100644 --- a/internal/lagoon/tasks.go +++ b/internal/lagoon/tasks.go @@ -12,6 +12,7 @@ import ( type Tasks interface { RunActiveStandbySwitch(ctx context.Context, project string, result *schema.Task) error GetTaskByID(ctx context.Context, id int, result *schema.Task) error + EnvironmentAndTasksByEnvironmentName(ctx context.Context, name string, projectID uint, environment *schema.Environment) error } // ActiveStandbySwitch runs the activestandby switch. @@ -25,3 +26,8 @@ func TaskByID(ctx context.Context, id int, t Tasks) (*schema.Task, error) { result := schema.Task{} return &result, t.GetTaskByID(ctx, id, &result) } + +func TasksForEnvironment(ctx context.Context, projectId uint, environmentName string, t Tasks) (*schema.Environment, error) { + result := schema.Environment{} + return &result, t.EnvironmentAndTasksByEnvironmentName(ctx, environmentName, projectId, &result) +} diff --git a/internal/schema/environment.go b/internal/schema/environment.go index bc7af0e7..efe0fe3a 100644 --- a/internal/schema/environment.go +++ b/internal/schema/environment.go @@ -19,17 +19,33 @@ type AddEnvironmentInput struct { // Environment is the Lagoon API Environment object. type Environment struct { AddEnvironmentInput - AutoIdle uint `json:"autoIdle"` - EnvVariables []EnvKeyValue `json:"envVariables,omitempty"` - Route string `json:"route,omitempty"` - Routes string `json:"routes,omitempty"` - Backups []Backup `json:"backups,omitempty"` + AutoIdle uint `json:"autoIdle"` + EnvVariables []EnvKeyValue `json:"envVariables,omitempty"` + Route string `json:"route,omitempty"` + Routes string `json:"routes,omitempty"` + Backups []Backup `json:"backups,omitempty"` + AdvancedTasks []AdvancedTaskDefinition `json:"advancedTasks"` // TODO use a unixtime type Updated string `json:"updated,omitempty"` Created string `json:"created,omitempty"` Deleted string `json:"deleted,omitempty"` } +type AdvancedTaskDefinition struct { + Id uint `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AdvancedTaskDefinitionArguments []AdvancedTaskDefinitionArgument `json:"advancedTaskDefinitionArguments"` +} + +type AdvancedTaskDefinitionArgument struct { + Id uint `json:"id"` + Name string `json:"name"` + DisplayName string `json:"displayName"` + Type string `json:"type"` + Range []string `json:"range"` +} + // EnvironmentConfig contains Environment configuration. type EnvironmentConfig struct { Environment From 97744f0620da85b605e16c47fdd32ee5ee6d0e58 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Feb 2023 16:04:00 +1300 Subject: [PATCH 07/15] Changes 'invoke' command name to 'run' --- cmd/tasks.go | 8 +++--- docs/commands/lagoon_run.md | 2 +- docs/commands/lagoon_run_task.md | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 docs/commands/lagoon_run_task.md diff --git a/cmd/tasks.go b/cmd/tasks.go index 8c09b2ee..e93a0bef 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -188,13 +188,13 @@ var runDrushCacheClear = &cobra.Command{ } var invokeDefinedTask = &cobra.Command{ - Use: "invoke", + Use: "task", Aliases: []string{"i"}, - Short: "Invoke a custom task registered against an environment", - Long: `Invoke a custom task registered against an environment + Short: "Run a custom task registered against an environment", + Long: `Run a custom task registered against an environment The following are supported methods to use Direct: - lagoon run invoke -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] + lagoon run run -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] `, Run: func(cmd *cobra.Command, args []string) { if cmdProjectName == "" || cmdProjectEnvironment == "" || invokedTaskName == "" { diff --git a/docs/commands/lagoon_run.md b/docs/commands/lagoon_run.md index 7ee006e7..ff70f4de 100644 --- a/docs/commands/lagoon_run.md +++ b/docs/commands/lagoon_run.md @@ -37,5 +37,5 @@ Run a task against an environment * [lagoon run drush-archivedump](lagoon_run_drush-archivedump.md) - Run a drush archive dump on an environment * [lagoon run drush-cacheclear](lagoon_run_drush-cacheclear.md) - Run a drush cache clear on an environment * [lagoon run drush-sqldump](lagoon_run_drush-sqldump.md) - Run a drush sql dump on an environment -* [lagoon run invoke](lagoon_run_invoke.md) - Invoke a custom task registered against an environment +* [lagoon run task](lagoon_run_task.md) - Run a custom task registered against an environment diff --git a/docs/commands/lagoon_run_task.md b/docs/commands/lagoon_run_task.md new file mode 100644 index 00000000..ec5b6518 --- /dev/null +++ b/docs/commands/lagoon_run_task.md @@ -0,0 +1,45 @@ +## lagoon run task + +Run a custom task registered against an environment + +### Synopsis + +Run a custom task registered against an environment +The following are supported methods to use +Direct: + lagoon run run -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] + + +``` +lagoon run task [flags] +``` + +### Options + +``` + --argument strings Arguments to be passed to invoked task, of the form NAME=VALUE + -h, --help help for task + -N, --name string Name of the task that will be invoked +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication +``` + +### SEE ALSO + +* [lagoon run](lagoon_run.md) - Run a task against an environment + From 70fd07a97e35d258cdf79e5f5155c9782c41ea71 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Feb 2023 16:07:02 +1300 Subject: [PATCH 08/15] Further renaming of 'invoke' to 'run' --- cmd/run.go | 2 +- cmd/tasks.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index e22d4538..55aba2e3 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -19,5 +19,5 @@ func init() { runCmd.AddCommand(runDrushCacheClear) runCmd.AddCommand(runDrushSQLDump) runCmd.AddCommand(runActiveStandbySwitch) - runCmd.AddCommand(invokeDefinedTask) + runCmd.AddCommand(runDefinedTask) } diff --git a/cmd/tasks.go b/cmd/tasks.go index e93a0bef..4ee0b9bb 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -187,7 +187,7 @@ var runDrushCacheClear = &cobra.Command{ }, } -var invokeDefinedTask = &cobra.Command{ +var runDefinedTask = &cobra.Command{ Use: "task", Aliases: []string{"i"}, Short: "Run a custom task registered against an environment", @@ -292,8 +292,8 @@ var ( ) func init() { - invokeDefinedTask.Flags().StringVarP(&invokedTaskName, "name", "N", "", "Name of the task that will be invoked") - invokeDefinedTask.Flags().StringSliceVar(&invokedTaskArguments, "argument", []string{}, "Arguments to be passed to invoked task, of the form NAME=VALUE") + runDefinedTask.Flags().StringVarP(&invokedTaskName, "name", "N", "", "Name of the task that will be run") + runDefinedTask.Flags().StringSliceVar(&invokedTaskArguments, "argument", []string{}, "Arguments to be passed to custom task, of the form NAME=VALUE") runCustomTask.Flags().StringVarP(&taskName, "name", "N", "Custom Task", "Name of the task that will show in the UI (default: Custom Task)") runCustomTask.Flags().StringVarP(&taskService, "service", "S", "cli", "Name of the service (cli, nginx, other) that should run the task (default: cli)") runCustomTask.Flags().StringVarP(&taskCommand, "command", "c", "", "The command to run in the task") From 0533bcb034aa67775c152ef077d13bb1b71bedb7 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Feb 2023 16:28:42 +1300 Subject: [PATCH 09/15] Updates select for tasks --- cmd/tasks.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index 7170056c..12e8d3c6 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -272,10 +272,9 @@ example: Label: "Select Task", Items: environment.AdvancedTasks, Templates: &promptui.SelectTemplates{ - Active: "\U0001F336 {{ .Name }}", - Inactive: " {{ .Name }}", - Selected: "\U0001F336 {{ .Name | red | cyan }}", - Details: `{{ .Name }} -- {{ .Description }}`, + Active: fmt.Sprintf("%s {{ .Name | underline }} -- {{ .Description }}", promptui.IconSelect), + Inactive: "{{ .Name }} -- {{ .Description }}", + Selected: fmt.Sprintf("%s {{ .Name | green }}", promptui.IconGood), }, } From 55debbf32e7329fa155301e617473e81c7bf09fb Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Feb 2023 17:00:02 +1300 Subject: [PATCH 10/15] Adds omitempty on AdvancedTasks --- cmd/tasks.go | 3 --- internal/schema/environment.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index 12e8d3c6..ced03972 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -254,8 +254,6 @@ example: return } - //TODO: get list of tasks and their arguments - environment, err := lagoon.TasksForEnvironment(context.TODO(), project.ID, cmdProjectEnvironment, lc) if err != nil { @@ -285,7 +283,6 @@ example: return } - //TODO: fill out any arguments task := environment.AdvancedTasks[taskIndex] taskArguments := map[string]string{} taskArgumentString := "" diff --git a/internal/schema/environment.go b/internal/schema/environment.go index efe0fe3a..a7609da5 100644 --- a/internal/schema/environment.go +++ b/internal/schema/environment.go @@ -24,7 +24,7 @@ type Environment struct { Route string `json:"route,omitempty"` Routes string `json:"routes,omitempty"` Backups []Backup `json:"backups,omitempty"` - AdvancedTasks []AdvancedTaskDefinition `json:"advancedTasks"` + AdvancedTasks []AdvancedTaskDefinition `json:"advancedTasks,omitempty"` // TODO use a unixtime type Updated string `json:"updated,omitempty"` Created string `json:"created,omitempty"` From fc98099e517f3e4f4501115c3d92a0ecfae82d23 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Feb 2023 18:58:58 +1300 Subject: [PATCH 11/15] Fixes Thinko --- cmd/tasks.go | 2 +- docs/commands/lagoon_run_task.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index 4ee0b9bb..8e54ada7 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -194,7 +194,7 @@ var runDefinedTask = &cobra.Command{ Long: `Run a custom task registered against an environment The following are supported methods to use Direct: - lagoon run run -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] + lagoon run task -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] `, Run: func(cmd *cobra.Command, args []string) { if cmdProjectName == "" || cmdProjectEnvironment == "" || invokedTaskName == "" { diff --git a/docs/commands/lagoon_run_task.md b/docs/commands/lagoon_run_task.md index ec5b6518..27f24cee 100644 --- a/docs/commands/lagoon_run_task.md +++ b/docs/commands/lagoon_run_task.md @@ -7,7 +7,7 @@ Run a custom task registered against an environment Run a custom task registered against an environment The following are supported methods to use Direct: - lagoon run run -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] + lagoon run task -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] ``` @@ -17,9 +17,9 @@ lagoon run task [flags] ### Options ``` - --argument strings Arguments to be passed to invoked task, of the form NAME=VALUE + --argument strings Arguments to be passed to custom task, of the form NAME=VALUE -h, --help help for task - -N, --name string Name of the task that will be invoked + -N, --name string Name of the task that will be run ``` ### Options inherited from parent commands From aae615351d0f6c2368a91534862c7aa8c5b1d4c8 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Tue, 21 Feb 2023 08:47:02 +1300 Subject: [PATCH 12/15] Better prompt formatting --- cmd/tasks.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index 579d9112..bb67a876 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -240,7 +240,6 @@ example: os.Exit(1) } - //TODO: get project id for subsequent queries current := lagoonCLIConfig.Current lc := client.New( lagoonCLIConfig.Lagoons[current].GraphQL, @@ -262,17 +261,17 @@ example: } if len(environment.AdvancedTasks) == 0 { - fmt.Println("No custom tasks registered against environment - exiting") + fmt.Printf("There are no custom tasks registered against %v %v\n", cmdProjectName, environment.Name) return } prompt := promptui.Select{ - Label: "Select Task", + Label: "Select", //fmt.Sprintf("Select a custom task to run on %v %v\n", cmdProjectName, environment.Name), Items: environment.AdvancedTasks, Templates: &promptui.SelectTemplates{ Active: fmt.Sprintf("%s {{ .Name | underline }} -- {{ .Description }}", promptui.IconSelect), - Inactive: "{{ .Name }} -- {{ .Description }}", - Selected: fmt.Sprintf("%s {{ .Name | green }}", promptui.IconGood), + Inactive: " {{ .Name }} -- {{ .Description }}", + Selected: fmt.Sprintf("Task: {{ .Name }}"), }, } @@ -285,23 +284,30 @@ example: task := environment.AdvancedTasks[taskIndex] taskArguments := map[string]string{} - taskArgumentString := "" for _, v := range task.AdvancedTaskDefinitionArguments { if len(v.Range) != 0 { //we have a selection - prompt = promptui.Select{ - Label: v.DisplayName, + argPrompt := promptui.Select{ + Label: fmt.Sprintf("%v", v.DisplayName), Items: v.Range, + Templates: &promptui.SelectTemplates{ + Active: fmt.Sprintf("%s {{ . | underline }}", promptui.IconSelect), + Inactive: " {{ . }}", + Selected: fmt.Sprintf("-- %s : {{ . }}", v.DisplayName), + }, } - _, argumentValue, err := prompt.Run() + _, argumentValue, err := argPrompt.Run() if err != nil { fmt.Printf("Prompt failed %v\n", err) return } taskArguments[v.Name] = argumentValue - taskArgumentString = taskArgumentString + fmt.Sprintf("%v(%v) : %v", v.DisplayName, v.Name, argumentValue) } else { // standard prompt prompt := promptui.Prompt{ Label: fmt.Sprintf("%v", v.DisplayName), + Templates: &promptui.PromptTemplates{ + Valid: fmt.Sprintf("-- {{ . }} : "), + Success: fmt.Sprintf("-- {{ . }} : "), + }, } argumentValue, err := prompt.Run() @@ -310,11 +316,10 @@ example: return } taskArguments[v.Name] = argumentValue - taskArgumentString = taskArgumentString + fmt.Sprintf(", %v(%v) : %v", v.DisplayName, v.Name, argumentValue) } } - if !yesNo(fmt.Sprintf("Run command `%v` with arguments %v", task.Name, taskArgumentString)) { + if !yesNo(fmt.Sprintf("Run above command on %s %s", cmdProjectName, cmdProjectEnvironment)) { fmt.Println("Exiting") return } From 9e8f8bae29dd42aa69ce76e3de18b2b9e3b49a34 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Tue, 21 Feb 2023 08:47:44 +1300 Subject: [PATCH 13/15] Updates docs --- docs/commands/lagoon_run_task.md | 1 + docs/commands/lagoon_run_task_interactive.md | 43 ++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 docs/commands/lagoon_run_task_interactive.md diff --git a/docs/commands/lagoon_run_task.md b/docs/commands/lagoon_run_task.md index 27f24cee..a4deacd9 100644 --- a/docs/commands/lagoon_run_task.md +++ b/docs/commands/lagoon_run_task.md @@ -42,4 +42,5 @@ lagoon run task [flags] ### SEE ALSO * [lagoon run](lagoon_run.md) - Run a task against an environment +* [lagoon run task interactive](lagoon_run_task_interactive.md) - Interactively run a custom task against an environment diff --git a/docs/commands/lagoon_run_task_interactive.md b/docs/commands/lagoon_run_task_interactive.md new file mode 100644 index 00000000..9f63bc7b --- /dev/null +++ b/docs/commands/lagoon_run_task_interactive.md @@ -0,0 +1,43 @@ +## lagoon run task interactive + +Interactively run a custom task against an environment + +### Synopsis + +Interactively run a custom task against an environment +Provides prompts for arguments +example: + lagoon run invoke interactive -p example -e main + + +``` +lagoon run task interactive [flags] +``` + +### Options + +``` + -h, --help help for interactive +``` + +### Options inherited from parent commands + +``` + --config-file string Path to the config file to use (must be *.yml or *.yaml) + --debug Enable debugging output (if supported) + -e, --environment string Specify an environment to use + --force Force yes on prompts (if supported) + -l, --lagoon string The Lagoon instance to interact with + --no-header No header on table (if supported) + --output-csv Output as CSV (if supported) + --output-json Output as JSON (if supported) + --pretty Make JSON pretty (if supported) + -p, --project string Specify a project to use + --skip-update-check Skip checking for updates + -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication +``` + +### SEE ALSO + +* [lagoon run task](lagoon_run_task.md) - Run a custom task registered against an environment + From 8ef553c03187ac2eff6bfa6112f6c3bca7293ecf Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Tue, 21 Feb 2023 08:59:01 +1300 Subject: [PATCH 14/15] updates docs --- cmd/tasks.go | 2 +- docs/commands/lagoon_run_task_interactive.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/tasks.go b/cmd/tasks.go index bb67a876..7b5f3b7d 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -230,7 +230,7 @@ var invokeInteractiveTask = &cobra.Command{ Long: `Interactively run a custom task against an environment Provides prompts for arguments example: - lagoon run invoke interactive -p example -e main + lagoon run task interactive -p example -e main `, Run: func(cmd *cobra.Command, args []string) { debug, err := cmd.Flags().GetBool("debug") diff --git a/docs/commands/lagoon_run_task_interactive.md b/docs/commands/lagoon_run_task_interactive.md index 9f63bc7b..ca2c4f9a 100644 --- a/docs/commands/lagoon_run_task_interactive.md +++ b/docs/commands/lagoon_run_task_interactive.md @@ -7,7 +7,7 @@ Interactively run a custom task against an environment Interactively run a custom task against an environment Provides prompts for arguments example: - lagoon run invoke interactive -p example -e main + lagoon run task interactive -p example -e main ``` From 2a4e42d370dae065bea5ee455b1c5346ef5f91ca Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Tue, 21 Feb 2023 13:12:08 +1300 Subject: [PATCH 15/15] Removes old docs and comment --- cmd/tasks.go | 2 +- docs/commands/lagoon_run_invoke.md | 45 ------------------------------ 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 docs/commands/lagoon_run_invoke.md diff --git a/cmd/tasks.go b/cmd/tasks.go index 7b5f3b7d..718152f5 100644 --- a/cmd/tasks.go +++ b/cmd/tasks.go @@ -266,7 +266,7 @@ example: } prompt := promptui.Select{ - Label: "Select", //fmt.Sprintf("Select a custom task to run on %v %v\n", cmdProjectName, environment.Name), + Label: "Select", Items: environment.AdvancedTasks, Templates: &promptui.SelectTemplates{ Active: fmt.Sprintf("%s {{ .Name | underline }} -- {{ .Description }}", promptui.IconSelect), diff --git a/docs/commands/lagoon_run_invoke.md b/docs/commands/lagoon_run_invoke.md deleted file mode 100644 index d1cc69e3..00000000 --- a/docs/commands/lagoon_run_invoke.md +++ /dev/null @@ -1,45 +0,0 @@ -## lagoon run invoke - -Invoke a custom task registered against an environment - -### Synopsis - -Invoke a custom task registered against an environment -The following are supported methods to use -Direct: - lagoon run invoke -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..] - - -``` -lagoon run invoke [flags] -``` - -### Options - -``` - --argument strings Arguments to be passed to invoked task, of the form NAME=VALUE - -h, --help help for invoke - -N, --name string Name of the task that will be invoked -``` - -### Options inherited from parent commands - -``` - --config-file string Path to the config file to use (must be *.yml or *.yaml) - --debug Enable debugging output (if supported) - -e, --environment string Specify an environment to use - --force Force yes on prompts (if supported) - -l, --lagoon string The Lagoon instance to interact with - --no-header No header on table (if supported) - --output-csv Output as CSV (if supported) - --output-json Output as JSON (if supported) - --pretty Make JSON pretty (if supported) - -p, --project string Specify a project to use - --skip-update-check Skip checking for updates - -i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication -``` - -### SEE ALSO - -* [lagoon run](lagoon_run.md) - Run a task against an environment -