nomad: update validate to check group networks for task port usage

This commit is contained in:
Nick Ethier
2020-08-28 12:38:30 -04:00
committed by Seth Hoenig
parent cb74d3f62e
commit c291dd1e94
5 changed files with 58 additions and 66 deletions

View File

@@ -5809,9 +5809,7 @@ func TestJobEndpoint_ValidateJob_ConsulConnect(t *testing.T) {
tg := j.TaskGroups[0]
tg.Services = tgServices
tg.Networks = structs.Networks{
{Mode: "bridge"},
}
tg.Networks[0].Mode = "bridge"
err := validateJob(j)
require.NoError(t, err)

View File

@@ -209,6 +209,14 @@ func Job() *structs.Job {
DelayFunction: "constant",
},
Migrate: structs.DefaultMigrateStrategy(),
Networks: []*structs.NetworkResource{
{
DynamicPorts: []structs.Port{
{Label: "http"},
{Label: "admin"},
},
},
},
Tasks: []*structs.Task{
{
Name: "web",
@@ -244,15 +252,6 @@ func Job() *structs.Job {
Resources: &structs.Resources{
CPU: 500,
MemoryMB: 256,
Networks: []*structs.NetworkResource{
{
MBits: 50,
DynamicPorts: []structs.Port{
{Label: "http"},
{Label: "admin"},
},
},
},
},
Meta: map[string]string{
"foo": "bar",

View File

@@ -6143,7 +6143,7 @@ func (tg *TaskGroup) Validate(j *Job) error {
}
}
if err := task.Validate(tg.EphemeralDisk, j.Type, tg.Services); err != nil {
if err := task.Validate(tg.EphemeralDisk, j.Type, tg.Services, tg.Networks); err != nil {
outer := fmt.Errorf("Task %s validation failed: %v", task.Name, err)
mErr.Errors = append(mErr.Errors, outer)
}
@@ -6718,7 +6718,7 @@ func (t *Task) GoString() string {
}
// Validate is used to sanity check a task
func (t *Task) Validate(ephemeralDisk *EphemeralDisk, jobType string, tgServices []*Service) error {
func (t *Task) Validate(ephemeralDisk *EphemeralDisk, jobType string, tgServices []*Service, tgNetworks Networks) error {
var mErr multierror.Error
if t.Name == "" {
mErr.Errors = append(mErr.Errors, errors.New("Missing task name"))
@@ -6781,7 +6781,7 @@ func (t *Task) Validate(ephemeralDisk *EphemeralDisk, jobType string, tgServices
}
// Validate Services
if err := validateServices(t); err != nil {
if err := validateServices(t, tgNetworks); err != nil {
mErr.Errors = append(mErr.Errors, err)
}
@@ -6879,7 +6879,7 @@ func (t *Task) Validate(ephemeralDisk *EphemeralDisk, jobType string, tgServices
// validateServices takes a task and validates the services within it are valid
// and reference ports that exist.
func validateServices(t *Task) error {
func validateServices(t *Task, tgNetworks Networks) error {
var mErr multierror.Error
// Ensure that services don't ask for nonexistent ports and their names are
@@ -6976,12 +6976,10 @@ func validateServices(t *Task) error {
// Get the set of port labels.
portLabels := make(map[string]struct{})
if t.Resources != nil {
for _, network := range t.Resources.Networks {
ports := network.PortLabels()
for portLabel := range ports {
portLabels[portLabel] = struct{}{}
}
if len(tgNetworks) > 0 {
ports := tgNetworks[0].PortLabels()
for portLabel := range ports {
portLabels[portLabel] = struct{}{}
}
}

View File

@@ -1349,7 +1349,7 @@ func TestTaskGroupNetwork_Validate(t *testing.T) {
func TestTask_Validate(t *testing.T) {
task := &Task{}
ephemeralDisk := DefaultEphemeralDisk()
err := task.Validate(ephemeralDisk, JobTypeBatch, nil)
err := task.Validate(ephemeralDisk, JobTypeBatch, nil, nil)
mErr := err.(*multierror.Error)
if !strings.Contains(mErr.Errors[0].Error(), "task name") {
t.Fatalf("err: %s", err)
@@ -1362,7 +1362,7 @@ func TestTask_Validate(t *testing.T) {
}
task = &Task{Name: "web/foo"}
err = task.Validate(ephemeralDisk, JobTypeBatch, nil)
err = task.Validate(ephemeralDisk, JobTypeBatch, nil, nil)
mErr = err.(*multierror.Error)
if !strings.Contains(mErr.Errors[0].Error(), "slashes") {
t.Fatalf("err: %s", err)
@@ -1378,7 +1378,7 @@ func TestTask_Validate(t *testing.T) {
LogConfig: DefaultLogConfig(),
}
ephemeralDisk.SizeMB = 200
err = task.Validate(ephemeralDisk, JobTypeBatch, nil)
err = task.Validate(ephemeralDisk, JobTypeBatch, nil, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -1392,7 +1392,7 @@ func TestTask_Validate(t *testing.T) {
LTarget: "${meta.rack}",
})
err = task.Validate(ephemeralDisk, JobTypeBatch, nil)
err = task.Validate(ephemeralDisk, JobTypeBatch, nil, nil)
mErr = err.(*multierror.Error)
if !strings.Contains(mErr.Errors[0].Error(), "task level: distinct_hosts") {
t.Fatalf("err: %s", err)
@@ -1519,7 +1519,7 @@ func TestTask_Validate_Services(t *testing.T) {
Services: []*Service{s3, s4},
LogConfig: DefaultLogConfig(),
}
task1.Resources.Networks = []*NetworkResource{
tgNetworks := []*NetworkResource{
{
MBits: 10,
DynamicPorts: []Port{
@@ -1535,7 +1535,7 @@ func TestTask_Validate_Services(t *testing.T) {
},
}
err := task.Validate(ephemeralDisk, JobTypeService, nil)
err := task.Validate(ephemeralDisk, JobTypeService, nil, tgNetworks)
if err == nil {
t.Fatal("expected an error")
}
@@ -1556,7 +1556,7 @@ func TestTask_Validate_Services(t *testing.T) {
t.Fatalf("err: %v", err)
}
if err = task1.Validate(ephemeralDisk, JobTypeService, nil); err != nil {
if err = task1.Validate(ephemeralDisk, JobTypeService, nil, tgNetworks); err != nil {
t.Fatalf("err : %v", err)
}
}
@@ -1571,18 +1571,18 @@ func TestTask_Validate_Service_AddressMode_Ok(t *testing.T) {
Services: []*Service{s},
LogConfig: DefaultLogConfig(),
}
task.Resources.Networks = []*NetworkResource{
{
MBits: 10,
DynamicPorts: []Port{
{
Label: "http",
Value: 80,
},
return task
}
tgNetworks := []*NetworkResource{
{
DynamicPorts: []Port{
{
Label: "http",
Value: 80,
},
},
}
return task
},
}
cases := []*Service{
@@ -1615,7 +1615,7 @@ func TestTask_Validate_Service_AddressMode_Ok(t *testing.T) {
for _, service := range cases {
task := getTask(service)
t.Run(service.Name, func(t *testing.T) {
if err := task.Validate(ephemeralDisk, JobTypeService, nil); err != nil {
if err := task.Validate(ephemeralDisk, JobTypeService, nil, tgNetworks); err != nil {
t.Fatalf("unexpected err: %v", err)
}
})
@@ -1625,25 +1625,23 @@ func TestTask_Validate_Service_AddressMode_Ok(t *testing.T) {
func TestTask_Validate_Service_AddressMode_Bad(t *testing.T) {
ephemeralDisk := DefaultEphemeralDisk()
getTask := func(s *Service) *Task {
task := &Task{
return &Task{
Name: "web",
Driver: "docker",
Resources: DefaultResources(),
Services: []*Service{s},
LogConfig: DefaultLogConfig(),
}
task.Resources.Networks = []*NetworkResource{
{
MBits: 10,
DynamicPorts: []Port{
{
Label: "http",
Value: 80,
},
}
tgNetworks := []*NetworkResource{
{
DynamicPorts: []Port{
{
Label: "http",
Value: 80,
},
},
}
return task
},
}
cases := []*Service{
@@ -1668,7 +1666,7 @@ func TestTask_Validate_Service_AddressMode_Bad(t *testing.T) {
for _, service := range cases {
task := getTask(service)
t.Run(service.Name, func(t *testing.T) {
err := task.Validate(ephemeralDisk, JobTypeService, nil)
err := task.Validate(ephemeralDisk, JobTypeService, nil, tgNetworks)
if err == nil {
t.Fatalf("expected an error")
}
@@ -1785,9 +1783,10 @@ func TestTask_Validate_Service_Check(t *testing.T) {
// TestTask_Validate_Service_Check_AddressMode asserts that checks do not
// inherit address mode but do inherit ports.
func TestTask_Validate_Service_Check_AddressMode(t *testing.T) {
getTask := func(s *Service) *Task {
getTask := func(s *Service) (*Task, *TaskGroup) {
return &Task{
Resources: &Resources{
Services: []*Service{s},
}, &TaskGroup{
Networks: []*NetworkResource{
{
DynamicPorts: []Port{
@@ -1798,9 +1797,7 @@ func TestTask_Validate_Service_Check_AddressMode(t *testing.T) {
},
},
},
},
Services: []*Service{s},
}
}
}
cases := []struct {
@@ -1939,9 +1936,9 @@ func TestTask_Validate_Service_Check_AddressMode(t *testing.T) {
for _, tc := range cases {
tc := tc
task := getTask(tc.Service)
task, tg := getTask(tc.Service)
t.Run(tc.Service.Name, func(t *testing.T) {
err := validateServices(task)
err := validateServices(task, tg.Networks)
if err == nil && tc.ErrContains == "" {
// Ok!
return
@@ -2097,7 +2094,7 @@ func TestTask_Validate_ConnectProxyKind(t *testing.T) {
task.Services = []*Service{tc.Service}
}
t.Run(tc.Desc, func(t *testing.T) {
err := task.Validate(ephemeralDisk, "service", tc.TgService)
err := task.Validate(ephemeralDisk, "service", tc.TgService, nil)
if err == nil && tc.ErrContains == "" {
// Ok!
return
@@ -2116,7 +2113,7 @@ func TestTask_Validate_LogConfig(t *testing.T) {
SizeMB: 1,
}
err := task.Validate(ephemeralDisk, JobTypeService, nil)
err := task.Validate(ephemeralDisk, JobTypeService, nil, nil)
mErr := err.(*multierror.Error)
if !strings.Contains(mErr.Errors[3].Error(), "log storage") {
t.Fatalf("err: %s", err)
@@ -2189,7 +2186,7 @@ func TestTask_Validate_CSIPluginConfig(t *testing.T) {
SizeMB: 1,
}
err := task.Validate(ephemeralDisk, JobTypeService, nil)
err := task.Validate(ephemeralDisk, JobTypeService, nil, nil)
mErr := err.(*multierror.Error)
if tt.expectedErr != "" {
if !strings.Contains(mErr.Errors[4].Error(), tt.expectedErr) {
@@ -2214,7 +2211,7 @@ func TestTask_Validate_Template(t *testing.T) {
SizeMB: 1,
}
err := task.Validate(ephemeralDisk, JobTypeService, nil)
err := task.Validate(ephemeralDisk, JobTypeService, nil, nil)
if !strings.Contains(err.Error(), "Template 1 validation failed") {
t.Fatalf("err: %s", err)
}
@@ -2227,7 +2224,7 @@ func TestTask_Validate_Template(t *testing.T) {
}
task.Templates = []*Template{good, good}
err = task.Validate(ephemeralDisk, JobTypeService, nil)
err = task.Validate(ephemeralDisk, JobTypeService, nil, nil)
if !strings.Contains(err.Error(), "same destination as") {
t.Fatalf("err: %s", err)
}
@@ -2240,7 +2237,7 @@ func TestTask_Validate_Template(t *testing.T) {
},
}
err = task.Validate(ephemeralDisk, JobTypeService, nil)
err = task.Validate(ephemeralDisk, JobTypeService, nil, nil)
if err == nil {
t.Fatalf("expected error from Template.Validate")
}

View File

@@ -46,7 +46,7 @@ job "docs" {
## `network` Parameters
- `mbits` `([*deprecated*](/docs/upgrade/upgrade-specific#nomad-0-12-0) int: 10)` - Specifies the bandwidth required in MBits.
- `mbits` <code>([*deprecated*](/docs/upgrade/upgrade-specific#nomad-0-12-0) int: 10)</code> - Specifies the bandwidth required in MBits.
- `port` <code>([Port](#port-parameters): nil)</code> - Specifies a TCP/UDP port
allocation and can be used to specify both dynamic ports and reserved ports.