connect: enable configuring sidecar_task.name

Before, the submitted jobspec for sidecar_task would pass
through 2 key validation steps - once for the subset specific
to connect sidecar task definitions, and once again for the set
of normal task definition where the task would actually get
unmarshalled.

The valid keys for the normal task definition did not include
"name", which is supposed to be configurable for the sidecar
task. To fix this, just eliminate the double validation step,
and instead pass-in the correct set of keys to validate against
to the one generic task parser.

Fixes #7680
This commit is contained in:
Seth Hoenig
2020-04-09 21:01:16 -06:00
parent 5b65b95a0e
commit 729931aced
4 changed files with 97 additions and 68 deletions

View File

@@ -263,32 +263,7 @@ func parseSidecarService(o *ast.ObjectItem) (*api.ConsulSidecarService, error) {
}
func parseSidecarTask(item *ast.ObjectItem) (*api.SidecarTask, error) {
// We need this later
var listVal *ast.ObjectList
if ot, ok := item.Val.(*ast.ObjectType); ok {
listVal = ot.List
} else {
return nil, fmt.Errorf("should be an object")
}
// Check for invalid keys
valid := []string{
"config",
"driver",
"env",
"kill_timeout",
"logs",
"meta",
"resources",
"shutdown_delay",
"user",
"kill_signal",
}
if err := helper.CheckHCLKeys(listVal, valid); err != nil {
return nil, err
}
task, err := parseTask(item)
task, err := parseTask(item, sidecarTaskKeys)
if err != nil {
return nil, err
}

View File

@@ -12,47 +12,8 @@ import (
"github.com/mitchellh/mapstructure"
)
func parseTasks(result *[]*api.Task, list *ast.ObjectList) error {
list = list.Children()
if len(list.Items) == 0 {
return nil
}
// Go through each object and turn it into an actual result.
seen := make(map[string]struct{})
for _, item := range list.Items {
n := item.Keys[0].Token.Value().(string)
// Make sure we haven't already found this
if _, ok := seen[n]; ok {
return fmt.Errorf("task '%s' defined more than once", n)
}
seen[n] = struct{}{}
t, err := parseTask(item)
if err != nil {
return multierror.Prefix(err, fmt.Sprintf("'%s',", n))
}
t.Name = n
*result = append(*result, t)
}
return nil
}
func parseTask(item *ast.ObjectItem) (*api.Task, error) {
// We need this later
var listVal *ast.ObjectList
if ot, ok := item.Val.(*ast.ObjectType); ok {
listVal = ot.List
} else {
return nil, fmt.Errorf("should be an object")
}
// Check for invalid keys
valid := []string{
var (
normalTaskKeys = []string{
"artifact",
"config",
"constraint",
@@ -77,7 +38,63 @@ func parseTask(item *ast.ObjectItem) (*api.Task, error) {
"volume_mount",
"csi_plugin",
}
if err := helper.CheckHCLKeys(listVal, valid); err != nil {
sidecarTaskKeys = []string{
"name",
"driver",
"user",
"config",
"env",
"resources",
"meta",
"logs",
"kill_timeout",
"shutdown_delay",
"kill_signal",
}
)
func parseTasks(result *[]*api.Task, list *ast.ObjectList) error {
list = list.Children()
if len(list.Items) == 0 {
return nil
}
// Go through each object and turn it into an actual result.
seen := make(map[string]struct{})
for _, item := range list.Items {
n := item.Keys[0].Token.Value().(string)
// Make sure we haven't already found this
if _, ok := seen[n]; ok {
return fmt.Errorf("task '%s' defined more than once", n)
}
seen[n] = struct{}{}
t, err := parseTask(item, normalTaskKeys)
if err != nil {
return multierror.Prefix(err, fmt.Sprintf("'%s',", n))
}
t.Name = n
*result = append(*result, t)
}
return nil
}
func parseTask(item *ast.ObjectItem, keys []string) (*api.Task, error) {
// We need this later
var listVal *ast.ObjectList
if ot, ok := item.Val.(*ast.ObjectType); ok {
listVal = ot.List
} else {
return nil, fmt.Errorf("should be an object")
}
// Check for invalid keys
if err := helper.CheckHCLKeys(listVal, keys); err != nil {
return nil, err
}

View File

@@ -894,6 +894,28 @@ func TestParse(t *testing.T) {
},
false,
},
{
"service-connect-sidecar_task-name.hcl",
&api.Job{
ID: helper.StringToPtr("sidecar_task_name"),
Name: helper.StringToPtr("sidecar_task_name"),
Type: helper.StringToPtr("service"),
TaskGroups: []*api.TaskGroup{{
Name: helper.StringToPtr("group"),
Services: []*api.Service{{
Name: "example",
Connect: &api.ConsulConnect{
Native: false,
SidecarService: &api.ConsulSidecarService{},
SidecarTask: &api.SidecarTask{
Name: "my-sidecar",
},
},
}},
}},
},
false,
},
{
"reschedule-job.hcl",
&api.Job{

View File

@@ -0,0 +1,15 @@
job "sidecar_task_name" {
type = "service"
group "group" {
service {
name = "example"
connect {
sidecar_service {}
sidecar_task {
name = "my-sidecar"
}
}
}
}
}