diff --git a/nomad/job_endpoint_test.go b/nomad/job_endpoint_test.go index 6202a3ebf..fc065462d 100644 --- a/nomad/job_endpoint_test.go +++ b/nomad/job_endpoint_test.go @@ -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) diff --git a/nomad/mock/mock.go b/nomad/mock/mock.go index e8c555a10..2b2b4bbb6 100644 --- a/nomad/mock/mock.go +++ b/nomad/mock/mock.go @@ -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", diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index d1a21df38..23277771c 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -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{}{} } } diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index ad8184336..995de79d4 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -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") } diff --git a/website/pages/docs/job-specification/network.mdx b/website/pages/docs/job-specification/network.mdx index adb71ed66..fe3a2c5ed 100644 --- a/website/pages/docs/job-specification/network.mdx +++ b/website/pages/docs/job-specification/network.mdx @@ -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` ([*deprecated*](/docs/upgrade/upgrade-specific#nomad-0-12-0) int: 10) - Specifies the bandwidth required in MBits. - `port` ([Port](#port-parameters): nil) - Specifies a TCP/UDP port allocation and can be used to specify both dynamic ports and reserved ports.