Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/task invoke args #263

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions cmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"crypto/sha1"
"errors"
"fmt"
"regexp"
"strings"
Expand Down Expand Up @@ -53,3 +54,16 @@ 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 {
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
}
48 changes: 48 additions & 0 deletions cmd/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
})
}
}
2 changes: 1 addition & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ func init() {
runCmd.AddCommand(runDrushCacheClear)
runCmd.AddCommand(runDrushSQLDump)
runCmd.AddCommand(runActiveStandbySwitch)
runCmd.AddCommand(invokeDefinedTask)
runCmd.AddCommand(runDefinedTask)
}
32 changes: 20 additions & 12 deletions cmd/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,14 @@ var runDrushCacheClear = &cobra.Command{
},
}

var invokeDefinedTask = &cobra.Command{
Use: "invoke",
var runDefinedTask = &cobra.Command{
Use: "task",
Aliases: []string{"i"},
Short: "",
Long: `Invoke a 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"
lagoon run run -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..]
bomoko marked this conversation as resolved.
Show resolved Hide resolved
`,
Run: func(cmd *cobra.Command, args []string) {
if cmdProjectName == "" || cmdProjectEnvironment == "" || invokedTaskName == "" {
Expand All @@ -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)
Expand Down Expand Up @@ -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")
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")
Expand Down
2 changes: 1 addition & 1 deletion docs/commands/lagoon_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 task](lagoon_run_task.md) - Run a custom task registered against an environment

11 changes: 6 additions & 5 deletions docs/commands/lagoon_run_invoke.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
## 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"
lagoon run invoke -p example -e main -N "advanced task name" [--argument=NAME=VALUE|..]


```
Expand All @@ -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
Expand Down
45 changes: 45 additions & 0 deletions docs/commands/lagoon_run_task.md
Original file line number Diff line number Diff line change
@@ -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

41 changes: 19 additions & 22 deletions internal/lagoon/client/lgraphql/lgraphql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/lagoon/environments/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
21 changes: 18 additions & 3 deletions pkg/lagoon/environments/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -417,10 +417,24 @@ 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 {
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
Expand All @@ -429,6 +443,7 @@ func (e *Environments) InvokeAdvancedTaskDefinition(projectName string, environm
Variables: map[string]interface{}{
"advancedTaskDefinition": taskId,
"environment": environmentInfo.ID,
"taskArgumentValues": taskArgumentValues,
},
MappedResult: "invokeRegisteredTask",
}
Expand Down