mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 10:25:42 +03:00
nomad: update validate to check group networks for task port usage
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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{}{}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user