action: add job action name validation (#19145)

This commit is contained in:
James Rasell
2023-11-22 08:02:49 +00:00
committed by GitHub
parent e03e674135
commit 0f0b9a1a3c
5 changed files with 53 additions and 17 deletions

View File

@@ -1276,9 +1276,9 @@ func TestHTTP_JobActions(t *testing.T) {
// Two actions by default, both in Task web and Group web
must.Len(t, 2, actionsResp, must.Sprint("expected 2 actions"))
must.Eq(t, "date test", actionsResp[0].Name)
must.Eq(t, "date-test", actionsResp[0].Name)
must.Eq(t, "echo test", actionsResp[1].Name)
must.Eq(t, "echo-test", actionsResp[1].Name)
// Both have Args lists length of 1
must.Len(t, 1, actionsResp[0].Args, must.Sprint("expected 1 arg"))
@@ -1351,9 +1351,9 @@ func TestHTTP_JobActions(t *testing.T) {
dateTestCount := 0
echoTestCount := 0
for _, action := range actionsResp3 {
if action.Name == "date test" {
if action.Name == "date-test" {
dateTestCount++
} else if action.Name == "echo test" {
} else if action.Name == "echo-test" {
echoTestCount++
}
}

View File

@@ -81,12 +81,12 @@ func MockJob() *api.Job {
// actions
Actions: []*api.Action{
{
Name: "date test",
Name: "date-test",
Command: "/bin/date",
Args: []string{"-u"},
},
{
Name: "echo test",
Name: "echo-test",
Command: "/bin/echo",
Args: []string{"hello world"},
},

View File

@@ -78,12 +78,12 @@ func Job() *structs.Job {
},
Actions: []*structs.Action{
{
Name: "date test",
Name: "date-test",
Command: "/bin/date",
Args: []string{"-u"},
},
{
Name: "echo test",
Name: "echo-test",
Command: "/bin/echo",
Args: []string{"hello world"},
},
@@ -706,7 +706,7 @@ func BigBenchmarkJob() *structs.Job {
return job
}
// A multi-group, multi-task job with actions testing.
// ActionsJob produces a multi-group, multi-task job with actions for testing.
func ActionsJob() *structs.Job {
job := MinJob()
@@ -726,12 +726,12 @@ func ActionsJob() *structs.Job {
for _, task := range tg.Tasks {
task.Actions = []*structs.Action{
{
Name: "date test",
Name: "date-test",
Command: "/bin/date",
Args: []string{"-u"},
},
{
Name: "echo test",
Name: "echo-test",
Command: "/bin/echo",
Args: []string{"hello world"},
},

View File

@@ -9,11 +9,16 @@ package structs
import (
"errors"
"fmt"
"regexp"
"slices"
"github.com/hashicorp/go-multierror"
)
// validJobActionName is used to validate a job action name.
var validJobActionName = regexp.MustCompile("^[a-zA-Z0-9-]{1,128}$")
type Action struct {
Name string
Command string
@@ -60,7 +65,10 @@ func (a *Action) Validate() error {
var mErr *multierror.Error
if a.Command == "" {
mErr = multierror.Append(mErr, errors.New("Missing command"))
mErr = multierror.Append(mErr, errors.New("command cannot be empty"))
}
if !validJobActionName.MatchString(a.Name) {
mErr = multierror.Append(mErr, fmt.Errorf("invalid name '%s'", a.Name))
}
return mErr.ErrorOrNil()

View File

@@ -149,13 +149,41 @@ func TestAction_Validate(t *testing.T) {
expectedError: nil,
},
{
name: "empty command",
inputAction: &Action{},
expectedError: errors.New("Missing command"),
name: "empty command",
inputAction: &Action{
Name: "adrian-iv",
},
expectedError: errors.New("command cannot be empty"),
},
{
name: "valid",
inputAction: &Action{Command: "env"},
name: "empty name",
inputAction: &Action{
Command: "env",
},
expectedError: errors.New(`invalid name ''`),
},
{
name: "too long name",
inputAction: &Action{
Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Command: "env",
},
expectedError: errors.New(`invalid name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'`),
},
{
name: "invalid character name",
inputAction: &Action{
Name: `\//?|?|?%&%@$&£@$)`,
Command: "env",
},
expectedError: errors.New(`invalid name '\//?|?|?%&%@$&£@$)'`),
},
{
name: "valid",
inputAction: &Action{
Name: "adrian-iv",
Command: "env",
},
expectedError: nil,
},
}