2015-09-15 00:43:42 +00:00
|
|
|
package jobspec
|
|
|
|
|
|
|
|
import (
|
|
|
|
"path/filepath"
|
2017-02-22 20:30:05 +00:00
|
|
|
"reflect"
|
2015-09-23 20:44:08 +00:00
|
|
|
"strings"
|
2015-09-15 00:43:42 +00:00
|
|
|
"testing"
|
2015-09-20 21:18:10 +00:00
|
|
|
"time"
|
2015-09-15 00:43:42 +00:00
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
"github.com/hashicorp/nomad/api"
|
|
|
|
"github.com/hashicorp/nomad/helper"
|
2015-09-15 00:43:42 +00:00
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
2017-02-22 20:30:05 +00:00
|
|
|
"github.com/kr/pretty"
|
2016-08-16 22:22:26 +00:00
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
capi "github.com/hashicorp/consul/api"
|
2015-09-15 00:43:42 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestParse(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
File string
|
2017-02-22 20:30:05 +00:00
|
|
|
Result *api.Job
|
2015-09-15 00:43:42 +00:00
|
|
|
Err bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"basic.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("binstore-storagelocker"),
|
|
|
|
Name: helper.StringToPtr("binstore-storagelocker"),
|
|
|
|
Type: helper.StringToPtr("batch"),
|
|
|
|
Priority: helper.IntToPtr(52),
|
|
|
|
AllAtOnce: helper.BoolToPtr(true),
|
2015-09-15 00:43:42 +00:00
|
|
|
Datacenters: []string{"us2", "eu1"},
|
2017-02-22 20:30:05 +00:00
|
|
|
Region: helper.StringToPtr("fooregion"),
|
2017-09-07 23:56:15 +00:00
|
|
|
Namespace: helper.StringToPtr("foonamespace"),
|
2017-02-22 20:30:05 +00:00
|
|
|
VaultToken: helper.StringToPtr("foo"),
|
2015-09-15 00:43:42 +00:00
|
|
|
|
2015-09-15 00:46:52 +00:00
|
|
|
Meta: map[string]string{
|
|
|
|
"foo": "bar",
|
|
|
|
},
|
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-09-15 00:48:11 +00:00
|
|
|
LTarget: "kernel.os",
|
|
|
|
RTarget: "windows",
|
|
|
|
Operand: "=",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
Update: &api.UpdateStrategy{
|
2017-07-07 20:55:39 +00:00
|
|
|
Stagger: helper.TimeToPtr(60 * time.Second),
|
2017-05-09 00:44:26 +00:00
|
|
|
MaxParallel: helper.IntToPtr(2),
|
|
|
|
HealthCheck: helper.StringToPtr("manual"),
|
|
|
|
MinHealthyTime: helper.TimeToPtr(10 * time.Second),
|
|
|
|
HealthyDeadline: helper.TimeToPtr(10 * time.Minute),
|
|
|
|
AutoRevert: helper.BoolToPtr(true),
|
|
|
|
Canary: helper.IntToPtr(1),
|
2015-09-20 21:18:10 +00:00
|
|
|
},
|
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
TaskGroups: []*api.TaskGroup{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("outside"),
|
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-09-15 00:43:42 +00:00
|
|
|
Name: "outside",
|
|
|
|
Driver: "java",
|
2015-11-15 08:10:48 +00:00
|
|
|
Config: map[string]interface{}{
|
2016-04-09 22:38:42 +00:00
|
|
|
"jar_path": "s3://my-cool-store/foo.jar",
|
2015-09-15 00:43:42 +00:00
|
|
|
},
|
|
|
|
Meta: map[string]string{
|
|
|
|
"my-cool-key": "foobar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("binsl"),
|
|
|
|
Count: helper.IntToPtr(5),
|
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-09-15 00:43:42 +00:00
|
|
|
LTarget: "kernel.os",
|
|
|
|
RTarget: "linux",
|
|
|
|
Operand: "=",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Meta: map[string]string{
|
|
|
|
"elb_mode": "tcp",
|
|
|
|
"elb_interval": "10",
|
|
|
|
"elb_checks": "3",
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
RestartPolicy: &api.RestartPolicy{
|
|
|
|
Interval: helper.TimeToPtr(10 * time.Minute),
|
|
|
|
Attempts: helper.IntToPtr(5),
|
|
|
|
Delay: helper.TimeToPtr(15 * time.Second),
|
|
|
|
Mode: helper.StringToPtr("delay"),
|
2015-10-30 23:32:05 +00:00
|
|
|
},
|
2018-01-18 20:49:01 +00:00
|
|
|
ReschedulePolicy: &api.ReschedulePolicy{
|
|
|
|
Interval: helper.TimeToPtr(12 * time.Hour),
|
|
|
|
Attempts: helper.IntToPtr(5),
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
EphemeralDisk: &api.EphemeralDisk{
|
|
|
|
Sticky: helper.BoolToPtr(true),
|
|
|
|
SizeMB: helper.IntToPtr(150),
|
2016-08-24 18:51:15 +00:00
|
|
|
},
|
2017-05-09 00:44:26 +00:00
|
|
|
Update: &api.UpdateStrategy{
|
|
|
|
MaxParallel: helper.IntToPtr(3),
|
|
|
|
HealthCheck: helper.StringToPtr("checks"),
|
|
|
|
MinHealthyTime: helper.TimeToPtr(1 * time.Second),
|
|
|
|
HealthyDeadline: helper.TimeToPtr(1 * time.Minute),
|
|
|
|
AutoRevert: helper.BoolToPtr(false),
|
|
|
|
Canary: helper.IntToPtr(2),
|
|
|
|
},
|
2018-01-24 00:47:00 +00:00
|
|
|
Migrate: &api.MigrateStrategy{
|
|
|
|
MaxParallel: helper.IntToPtr(2),
|
|
|
|
HealthCheck: helper.StringToPtr("task_states"),
|
|
|
|
MinHealthyTime: helper.TimeToPtr(11 * time.Second),
|
|
|
|
HealthyDeadline: helper.TimeToPtr(11 * time.Minute),
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-09-15 00:43:42 +00:00
|
|
|
Name: "binstore",
|
|
|
|
Driver: "docker",
|
2016-03-23 11:57:31 +00:00
|
|
|
User: "bob",
|
2015-11-15 08:10:48 +00:00
|
|
|
Config: map[string]interface{}{
|
2015-09-15 00:43:42 +00:00
|
|
|
"image": "hashicorp/binstore",
|
2016-04-25 21:58:31 +00:00
|
|
|
"labels": []map[string]interface{}{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2016-04-25 21:58:31 +00:00
|
|
|
"FOO": "bar",
|
|
|
|
},
|
|
|
|
},
|
2015-09-15 00:43:42 +00:00
|
|
|
},
|
2017-03-01 23:30:01 +00:00
|
|
|
Services: []*api.Service{
|
2015-11-17 06:51:08 +00:00
|
|
|
{
|
|
|
|
Tags: []string{"foo", "bar"},
|
|
|
|
PortLabel: "http",
|
2017-02-22 20:30:05 +00:00
|
|
|
Checks: []api.ServiceCheck{
|
2015-11-17 06:51:08 +00:00
|
|
|
{
|
2016-07-08 21:09:27 +00:00
|
|
|
Name: "check-name",
|
|
|
|
Type: "tcp",
|
|
|
|
PortLabel: "admin",
|
|
|
|
Interval: 10 * time.Second,
|
|
|
|
Timeout: 2 * time.Second,
|
2017-09-14 22:55:37 +00:00
|
|
|
CheckRestart: &api.CheckRestart{
|
|
|
|
Limit: 3,
|
|
|
|
Grace: helper.TimeToPtr(10 * time.Second),
|
|
|
|
IgnoreWarnings: true,
|
|
|
|
},
|
2015-11-17 06:51:08 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2015-09-30 16:18:43 +00:00
|
|
|
Env: map[string]string{
|
|
|
|
"HELLO": "world",
|
|
|
|
"LOREM": "ipsum",
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Resources: &api.Resources{
|
|
|
|
CPU: helper.IntToPtr(500),
|
|
|
|
MemoryMB: helper.IntToPtr(128),
|
|
|
|
Networks: []*api.NetworkResource{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
MBits: helper.IntToPtr(100),
|
2017-02-28 00:00:19 +00:00
|
|
|
ReservedPorts: []api.Port{{Label: "one", Value: 1}, {Label: "two", Value: 2}, {Label: "three", Value: 3}},
|
|
|
|
DynamicPorts: []api.Port{{Label: "http", Value: 0}, {Label: "https", Value: 0}, {Label: "admin", Value: 0}},
|
2015-09-15 01:27:37 +00:00
|
|
|
},
|
|
|
|
},
|
2015-09-15 00:43:42 +00:00
|
|
|
},
|
2017-08-17 00:54:11 +00:00
|
|
|
KillTimeout: helper.TimeToPtr(22 * time.Second),
|
|
|
|
ShutdownDelay: 11 * time.Second,
|
2017-02-22 20:30:05 +00:00
|
|
|
LogConfig: &api.LogConfig{
|
|
|
|
MaxFiles: helper.IntToPtr(14),
|
|
|
|
MaxFileSizeMB: helper.IntToPtr(101),
|
2016-02-05 07:28:01 +00:00
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Artifacts: []*api.TaskArtifact{
|
2016-03-14 18:13:43 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
GetterSource: helper.StringToPtr("http://foo.com/artifact"),
|
2016-03-14 22:46:06 +00:00
|
|
|
GetterOptions: map[string]string{
|
|
|
|
"checksum": "md5:b8a4f3f72ecab0510a6a31e997461c5f",
|
2016-03-14 18:13:43 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
GetterSource: helper.StringToPtr("http://bar.com/artifact"),
|
|
|
|
RelativeDest: helper.StringToPtr("test/foo/"),
|
2016-03-14 22:46:06 +00:00
|
|
|
GetterOptions: map[string]string{
|
|
|
|
"checksum": "md5:ff1cc0d3432dad54d607c1505fb7245c",
|
2016-03-14 18:13:43 +00:00
|
|
|
},
|
2017-07-06 03:44:49 +00:00
|
|
|
GetterMode: helper.StringToPtr("file"),
|
2016-03-14 18:13:43 +00:00
|
|
|
},
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Vault: &api.Vault{
|
2016-10-11 22:25:49 +00:00
|
|
|
Policies: []string{"foo", "bar"},
|
2017-02-22 20:30:05 +00:00
|
|
|
Env: helper.BoolToPtr(true),
|
|
|
|
ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart),
|
2016-08-09 23:07:45 +00:00
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Templates: []*api.Template{
|
2016-09-26 22:23:26 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
SourcePath: helper.StringToPtr("foo"),
|
|
|
|
DestPath: helper.StringToPtr("foo"),
|
|
|
|
ChangeMode: helper.StringToPtr("foo"),
|
|
|
|
ChangeSignal: helper.StringToPtr("foo"),
|
|
|
|
Splay: helper.TimeToPtr(10 * time.Second),
|
|
|
|
Perms: helper.StringToPtr("0644"),
|
2017-05-26 22:31:40 +00:00
|
|
|
Envvars: helper.BoolToPtr(true),
|
2017-08-01 21:14:08 +00:00
|
|
|
VaultGrace: helper.TimeToPtr(33 * time.Second),
|
2016-09-26 22:23:26 +00:00
|
|
|
},
|
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
SourcePath: helper.StringToPtr("bar"),
|
|
|
|
DestPath: helper.StringToPtr("bar"),
|
|
|
|
ChangeMode: helper.StringToPtr(structs.TemplateChangeModeRestart),
|
|
|
|
Splay: helper.TimeToPtr(5 * time.Second),
|
|
|
|
Perms: helper.StringToPtr("777"),
|
|
|
|
LeftDelim: helper.StringToPtr("--"),
|
|
|
|
RightDelim: helper.StringToPtr("__"),
|
2016-09-26 22:23:26 +00:00
|
|
|
},
|
|
|
|
},
|
2017-12-06 18:50:22 +00:00
|
|
|
Leader: true,
|
|
|
|
KillSignal: "",
|
2015-09-15 00:43:42 +00:00
|
|
|
},
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-09-15 00:43:42 +00:00
|
|
|
Name: "storagelocker",
|
2016-04-09 22:38:42 +00:00
|
|
|
Driver: "docker",
|
2016-03-23 11:57:31 +00:00
|
|
|
User: "",
|
2015-11-15 08:10:48 +00:00
|
|
|
Config: map[string]interface{}{
|
2015-09-15 00:43:42 +00:00
|
|
|
"image": "hashicorp/storagelocker",
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Resources: &api.Resources{
|
|
|
|
CPU: helper.IntToPtr(500),
|
|
|
|
MemoryMB: helper.IntToPtr(128),
|
|
|
|
IOPS: helper.IntToPtr(30),
|
2015-09-15 00:43:42 +00:00
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-09-15 00:50:34 +00:00
|
|
|
LTarget: "kernel.arch",
|
|
|
|
RTarget: "amd64",
|
|
|
|
Operand: "=",
|
|
|
|
},
|
|
|
|
},
|
2017-02-22 20:30:05 +00:00
|
|
|
Vault: &api.Vault{
|
2016-10-11 22:25:49 +00:00
|
|
|
Policies: []string{"foo", "bar"},
|
2017-02-22 20:30:05 +00:00
|
|
|
Env: helper.BoolToPtr(false),
|
|
|
|
ChangeMode: helper.StringToPtr(structs.VaultChangeModeSignal),
|
|
|
|
ChangeSignal: helper.StringToPtr("SIGUSR1"),
|
2016-10-11 22:25:49 +00:00
|
|
|
},
|
2015-09-15 00:43:42 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2015-09-15 01:30:26 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
"multi-network.hcl",
|
|
|
|
nil,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"multi-resource.hcl",
|
|
|
|
nil,
|
|
|
|
true,
|
|
|
|
},
|
2015-09-15 01:34:26 +00:00
|
|
|
|
2016-08-09 23:07:45 +00:00
|
|
|
{
|
|
|
|
"multi-vault.hcl",
|
|
|
|
nil,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
|
2015-09-15 01:34:26 +00:00
|
|
|
{
|
|
|
|
"default-job.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
2015-09-15 01:34:26 +00:00
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2015-09-17 05:06:55 +00:00
|
|
|
|
2015-10-11 19:20:58 +00:00
|
|
|
{
|
|
|
|
"version-constraint.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-10-11 19:20:58 +00:00
|
|
|
LTarget: "$attr.kernel.version",
|
|
|
|
RTarget: "~> 3.2",
|
2015-10-26 20:47:56 +00:00
|
|
|
Operand: structs.ConstraintVersion,
|
2015-10-11 19:20:58 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
|
2015-10-11 19:37:50 +00:00
|
|
|
{
|
|
|
|
"regexp-constraint.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-10-11 19:37:50 +00:00
|
|
|
LTarget: "$attr.kernel.version",
|
|
|
|
RTarget: "[0-9.]+",
|
2015-10-26 20:47:56 +00:00
|
|
|
Operand: structs.ConstraintRegex,
|
2015-10-11 19:37:50 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
|
2016-10-19 20:06:28 +00:00
|
|
|
{
|
|
|
|
"set-contains-constraint.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2016-10-19 20:06:28 +00:00
|
|
|
LTarget: "$meta.data",
|
|
|
|
RTarget: "foo,bar,baz",
|
|
|
|
Operand: structs.ConstraintSetContains,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
|
2015-10-22 23:37:20 +00:00
|
|
|
{
|
2015-10-23 00:40:41 +00:00
|
|
|
"distinctHosts-constraint.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-10-26 20:47:56 +00:00
|
|
|
Operand: structs.ConstraintDistinctHosts,
|
2015-10-22 23:37:20 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
|
2017-03-07 22:20:02 +00:00
|
|
|
{
|
|
|
|
"distinctProperty-constraint.hcl",
|
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Constraints: []*api.Constraint{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-03-07 22:20:02 +00:00
|
|
|
Operand: structs.ConstraintDistinctProperty,
|
|
|
|
LTarget: "${meta.rack}",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
|
2015-12-01 00:51:56 +00:00
|
|
|
{
|
|
|
|
"periodic-cron.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Periodic: &api.PeriodicConfig{
|
|
|
|
SpecType: helper.StringToPtr(api.PeriodicSpecCron),
|
|
|
|
Spec: helper.StringToPtr("*/5 * * *"),
|
|
|
|
ProhibitOverlap: helper.BoolToPtr(true),
|
|
|
|
TimeZone: helper.StringToPtr("Europe/Minsk"),
|
2015-12-01 00:51:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
|
2015-09-17 05:06:55 +00:00
|
|
|
{
|
|
|
|
"specify-job.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("job1"),
|
|
|
|
Name: helper.StringToPtr("My Job"),
|
2015-09-17 05:06:55 +00:00
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2015-11-16 18:00:06 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
"task-nested-config.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("bar"),
|
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-11-16 18:00:06 +00:00
|
|
|
Name: "bar",
|
|
|
|
Driver: "docker",
|
|
|
|
Config: map[string]interface{}{
|
2016-04-09 22:38:42 +00:00
|
|
|
"image": "hashicorp/image",
|
2015-11-16 18:00:06 +00:00
|
|
|
"port_map": []map[string]interface{}{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2015-11-16 18:00:06 +00:00
|
|
|
"db": 1234,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2016-04-09 22:38:42 +00:00
|
|
|
|
2016-03-16 03:21:52 +00:00
|
|
|
{
|
|
|
|
"bad-artifact.hcl",
|
|
|
|
nil,
|
|
|
|
true,
|
|
|
|
},
|
2016-03-18 19:01:46 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
"artifacts.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("binstore-storagelocker"),
|
|
|
|
Name: helper.StringToPtr("binstore-storagelocker"),
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("binsl"),
|
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2016-03-18 19:01:46 +00:00
|
|
|
Name: "binstore",
|
|
|
|
Driver: "docker",
|
2017-02-22 20:30:05 +00:00
|
|
|
Artifacts: []*api.TaskArtifact{
|
2016-03-18 19:01:46 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
GetterSource: helper.StringToPtr("http://foo.com/bar"),
|
2016-06-10 19:28:27 +00:00
|
|
|
GetterOptions: map[string]string{"foo": "bar"},
|
2017-02-22 20:30:05 +00:00
|
|
|
RelativeDest: helper.StringToPtr(""),
|
2016-03-18 19:01:46 +00:00
|
|
|
},
|
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
GetterSource: helper.StringToPtr("http://foo.com/baz"),
|
2016-06-10 19:28:27 +00:00
|
|
|
GetterOptions: nil,
|
2017-02-22 20:30:05 +00:00
|
|
|
RelativeDest: nil,
|
2016-03-18 19:01:46 +00:00
|
|
|
},
|
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
GetterSource: helper.StringToPtr("http://foo.com/bam"),
|
2016-06-10 19:28:27 +00:00
|
|
|
GetterOptions: nil,
|
2017-02-22 20:30:05 +00:00
|
|
|
RelativeDest: helper.StringToPtr("var/foo"),
|
2016-03-18 19:01:46 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2016-08-16 21:34:36 +00:00
|
|
|
{
|
|
|
|
"service-check-initial-status.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("check_initial_status"),
|
|
|
|
Name: helper.StringToPtr("check_initial_status"),
|
|
|
|
Type: helper.StringToPtr("service"),
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("group"),
|
|
|
|
Count: helper.IntToPtr(1),
|
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2016-08-16 21:34:36 +00:00
|
|
|
Name: "task",
|
2017-03-01 23:30:01 +00:00
|
|
|
Services: []*api.Service{
|
2016-08-16 21:34:36 +00:00
|
|
|
{
|
|
|
|
Tags: []string{"foo", "bar"},
|
|
|
|
PortLabel: "http",
|
2017-02-22 20:30:05 +00:00
|
|
|
Checks: []api.ServiceCheck{
|
2016-08-16 21:34:36 +00:00
|
|
|
{
|
|
|
|
Name: "check-name",
|
|
|
|
Type: "http",
|
2017-08-16 00:17:11 +00:00
|
|
|
Path: "/",
|
2016-08-16 21:34:36 +00:00
|
|
|
Interval: 10 * time.Second,
|
|
|
|
Timeout: 2 * time.Second,
|
2017-02-22 20:30:05 +00:00
|
|
|
InitialStatus: capi.HealthPassing,
|
2017-08-16 00:17:11 +00:00
|
|
|
Method: "POST",
|
|
|
|
Header: map[string][]string{
|
|
|
|
"Authorization": {"Basic ZWxhc3RpYzpjaGFuZ2VtZQ=="},
|
|
|
|
},
|
2016-08-16 21:34:36 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2017-08-17 22:25:51 +00:00
|
|
|
{
|
|
|
|
"service-check-bad-header.hcl",
|
|
|
|
nil,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"service-check-bad-header-2.hcl",
|
|
|
|
nil,
|
|
|
|
true,
|
|
|
|
},
|
2016-09-21 18:18:44 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
// TODO This should be pushed into the API
|
2016-09-21 18:18:44 +00:00
|
|
|
"vault_inheritance.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("example"),
|
|
|
|
Name: helper.StringToPtr("example"),
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("cache"),
|
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: "redis",
|
|
|
|
Vault: &api.Vault{
|
2016-10-11 22:25:49 +00:00
|
|
|
Policies: []string{"group"},
|
2017-02-22 20:30:05 +00:00
|
|
|
Env: helper.BoolToPtr(true),
|
|
|
|
ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart),
|
2016-09-21 18:18:44 +00:00
|
|
|
},
|
|
|
|
},
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: "redis2",
|
|
|
|
Vault: &api.Vault{
|
2016-10-11 22:25:49 +00:00
|
|
|
Policies: []string{"task"},
|
2017-02-22 20:30:05 +00:00
|
|
|
Env: helper.BoolToPtr(false),
|
|
|
|
ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart),
|
2016-09-21 18:18:44 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: helper.StringToPtr("cache2"),
|
|
|
|
Tasks: []*api.Task{
|
2017-09-26 22:26:33 +00:00
|
|
|
{
|
2017-02-22 20:30:05 +00:00
|
|
|
Name: "redis",
|
|
|
|
Vault: &api.Vault{
|
2016-10-11 22:25:49 +00:00
|
|
|
Policies: []string{"job"},
|
2017-02-22 20:30:05 +00:00
|
|
|
Env: helper.BoolToPtr(true),
|
|
|
|
ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart),
|
2016-09-21 18:18:44 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2016-11-23 23:48:36 +00:00
|
|
|
{
|
2017-01-20 18:33:52 +00:00
|
|
|
"parameterized_job.hcl",
|
2017-02-22 20:30:05 +00:00
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("parameterized_job"),
|
|
|
|
Name: helper.StringToPtr("parameterized_job"),
|
|
|
|
|
|
|
|
ParameterizedJob: &api.ParameterizedJobConfig{
|
2016-12-14 20:50:08 +00:00
|
|
|
Payload: "required",
|
2016-11-23 23:48:36 +00:00
|
|
|
MetaRequired: []string{"foo", "bar"},
|
|
|
|
MetaOptional: []string{"baz", "bam"},
|
|
|
|
},
|
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
2016-11-23 23:48:36 +00:00
|
|
|
Name: "bar",
|
|
|
|
Driver: "docker",
|
2017-02-22 20:30:05 +00:00
|
|
|
DispatchPayload: &api.DispatchPayloadConfig{
|
2016-12-14 20:50:08 +00:00
|
|
|
File: "foo/bar",
|
2016-11-23 23:48:36 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2017-11-30 21:53:35 +00:00
|
|
|
{
|
|
|
|
"job-with-kill-signal.hcl",
|
|
|
|
&api.Job{
|
2017-12-06 21:23:24 +00:00
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
2017-11-30 21:53:35 +00:00
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
2017-12-06 21:23:24 +00:00
|
|
|
Name: helper.StringToPtr("bar"),
|
2017-11-30 21:53:35 +00:00
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
2017-12-06 21:23:24 +00:00
|
|
|
Name: "bar",
|
2017-11-30 21:53:35 +00:00
|
|
|
Driver: "docker",
|
2017-12-06 21:23:24 +00:00
|
|
|
KillSignal: "SIGQUIT",
|
2017-11-30 21:53:35 +00:00
|
|
|
Config: map[string]interface{}{
|
|
|
|
"image": "hashicorp/image",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2017-12-05 19:39:42 +00:00
|
|
|
{
|
|
|
|
"service-check-driver-address.hcl",
|
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("address_mode_driver"),
|
|
|
|
Name: helper.StringToPtr("address_mode_driver"),
|
|
|
|
Type: helper.StringToPtr("service"),
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
|
|
|
Name: helper.StringToPtr("group"),
|
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
|
|
|
Name: "task",
|
|
|
|
Services: []*api.Service{
|
|
|
|
{
|
|
|
|
Name: "http-service",
|
|
|
|
PortLabel: "http",
|
|
|
|
AddressMode: "auto",
|
|
|
|
Checks: []api.ServiceCheck{
|
|
|
|
{
|
|
|
|
Name: "http-check",
|
|
|
|
Type: "http",
|
|
|
|
Path: "/",
|
|
|
|
PortLabel: "http",
|
|
|
|
AddressMode: "driver",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "random-service",
|
|
|
|
PortLabel: "9000",
|
|
|
|
AddressMode: "driver",
|
|
|
|
Checks: []api.ServiceCheck{
|
|
|
|
{
|
|
|
|
Name: "random-check",
|
|
|
|
Type: "tcp",
|
|
|
|
PortLabel: "9001",
|
|
|
|
AddressMode: "driver",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2018-01-04 23:04:45 +00:00
|
|
|
{
|
|
|
|
"service-check-restart.hcl",
|
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("service_check_restart"),
|
|
|
|
Name: helper.StringToPtr("service_check_restart"),
|
|
|
|
Type: helper.StringToPtr("service"),
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
|
|
|
Name: helper.StringToPtr("group"),
|
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
|
|
|
Name: "task",
|
|
|
|
Services: []*api.Service{
|
|
|
|
{
|
|
|
|
Name: "http-service",
|
|
|
|
CheckRestart: &api.CheckRestart{
|
|
|
|
Limit: 3,
|
|
|
|
Grace: helper.TimeToPtr(10 * time.Second),
|
|
|
|
IgnoreWarnings: true,
|
|
|
|
},
|
|
|
|
Checks: []api.ServiceCheck{
|
|
|
|
{
|
|
|
|
Name: "random-check",
|
|
|
|
Type: "tcp",
|
|
|
|
PortLabel: "9001",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2018-01-18 20:49:01 +00:00
|
|
|
{
|
|
|
|
"reschedule-job.hcl",
|
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Type: helper.StringToPtr("batch"),
|
|
|
|
Datacenters: []string{"dc1"},
|
|
|
|
Reschedule: &api.ReschedulePolicy{
|
2018-03-07 21:26:45 +00:00
|
|
|
Attempts: helper.IntToPtr(15),
|
|
|
|
Interval: helper.TimeToPtr(30 * time.Minute),
|
|
|
|
DelayFunction: helper.StringToPtr("linear"),
|
|
|
|
Delay: helper.TimeToPtr(10 * time.Second),
|
|
|
|
},
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
|
|
|
Name: helper.StringToPtr("bar"),
|
|
|
|
Count: helper.IntToPtr(3),
|
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
|
|
|
Name: "bar",
|
|
|
|
Driver: "raw_exec",
|
|
|
|
Config: map[string]interface{}{
|
|
|
|
"command": "bash",
|
|
|
|
"args": []interface{}{"-c", "echo hi"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"reschedule-job-unlimited.hcl",
|
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Type: helper.StringToPtr("batch"),
|
|
|
|
Datacenters: []string{"dc1"},
|
|
|
|
Reschedule: &api.ReschedulePolicy{
|
|
|
|
DelayFunction: helper.StringToPtr("exponential"),
|
|
|
|
Delay: helper.TimeToPtr(10 * time.Second),
|
2018-03-13 15:06:26 +00:00
|
|
|
MaxDelay: helper.TimeToPtr(120 * time.Second),
|
2018-03-07 21:26:45 +00:00
|
|
|
Unlimited: helper.BoolToPtr(true),
|
2018-01-18 20:49:01 +00:00
|
|
|
},
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
|
|
|
Name: helper.StringToPtr("bar"),
|
|
|
|
Count: helper.IntToPtr(3),
|
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
|
|
|
Name: "bar",
|
|
|
|
Driver: "raw_exec",
|
|
|
|
Config: map[string]interface{}{
|
|
|
|
"command": "bash",
|
|
|
|
"args": []interface{}{"-c", "echo hi"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2018-03-01 19:21:32 +00:00
|
|
|
{
|
|
|
|
"migrate-job.hcl",
|
|
|
|
&api.Job{
|
|
|
|
ID: helper.StringToPtr("foo"),
|
|
|
|
Name: helper.StringToPtr("foo"),
|
|
|
|
Type: helper.StringToPtr("batch"),
|
|
|
|
Datacenters: []string{"dc1"},
|
|
|
|
Migrate: &api.MigrateStrategy{
|
|
|
|
MaxParallel: helper.IntToPtr(2),
|
|
|
|
HealthCheck: helper.StringToPtr("task_states"),
|
|
|
|
MinHealthyTime: helper.TimeToPtr(11 * time.Second),
|
|
|
|
HealthyDeadline: helper.TimeToPtr(11 * time.Minute),
|
|
|
|
},
|
|
|
|
TaskGroups: []*api.TaskGroup{
|
|
|
|
{
|
|
|
|
Name: helper.StringToPtr("bar"),
|
|
|
|
Count: helper.IntToPtr(3),
|
|
|
|
Migrate: &api.MigrateStrategy{
|
|
|
|
MaxParallel: helper.IntToPtr(3),
|
|
|
|
HealthCheck: helper.StringToPtr("checks"),
|
|
|
|
MinHealthyTime: helper.TimeToPtr(1 * time.Second),
|
|
|
|
HealthyDeadline: helper.TimeToPtr(1 * time.Minute),
|
|
|
|
},
|
|
|
|
Tasks: []*api.Task{
|
|
|
|
{
|
|
|
|
Name: "bar",
|
|
|
|
Driver: "raw_exec",
|
|
|
|
Config: map[string]interface{}{
|
|
|
|
"command": "bash",
|
|
|
|
"args": []interface{}{"-c", "echo hi"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2015-09-15 00:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2015-11-09 06:57:39 +00:00
|
|
|
t.Logf("Testing parse: %s", tc.File)
|
|
|
|
|
2015-09-15 00:43:42 +00:00
|
|
|
path, err := filepath.Abs(filepath.Join("./test-fixtures", tc.File))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("file: %s\n\n%s", tc.File, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
actual, err := ParseFile(path)
|
2015-09-15 00:43:42 +00:00
|
|
|
if (err != nil) != tc.Err {
|
|
|
|
t.Fatalf("file: %s\n\n%s", tc.File, err)
|
|
|
|
continue
|
|
|
|
}
|
2017-02-22 20:30:05 +00:00
|
|
|
|
|
|
|
if !reflect.DeepEqual(actual, tc.Result) {
|
|
|
|
for _, d := range pretty.Diff(actual, tc.Result) {
|
|
|
|
t.Logf(d)
|
|
|
|
}
|
|
|
|
t.Fatalf("file: %s", tc.File)
|
|
|
|
}
|
2015-09-15 00:43:42 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-23 20:44:08 +00:00
|
|
|
|
|
|
|
func TestBadPorts(t *testing.T) {
|
|
|
|
path, err := filepath.Abs(filepath.Join("./test-fixtures", "bad-ports.hcl"))
|
|
|
|
if err != nil {
|
2016-04-09 22:38:42 +00:00
|
|
|
t.Fatalf("Can't get absolute path for file: %s", err)
|
2015-09-23 20:44:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_, err = ParseFile(path)
|
|
|
|
|
2015-11-15 08:10:48 +00:00
|
|
|
if !strings.Contains(err.Error(), errPortLabel.Error()) {
|
|
|
|
t.Fatalf("\nExpected error\n %s\ngot\n %v", errPortLabel, err)
|
2015-09-23 20:44:08 +00:00
|
|
|
}
|
2015-09-26 01:59:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestOverlappingPorts(t *testing.T) {
|
|
|
|
path, err := filepath.Abs(filepath.Join("./test-fixtures", "overlapping-ports.hcl"))
|
|
|
|
if err != nil {
|
2015-11-18 01:12:21 +00:00
|
|
|
t.Fatalf("Can't get absolute path for file: %s", err)
|
2015-09-26 01:59:17 +00:00
|
|
|
}
|
2015-09-23 20:44:08 +00:00
|
|
|
|
2015-09-26 01:59:17 +00:00
|
|
|
_, err = ParseFile(path)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Expected an error")
|
|
|
|
}
|
|
|
|
|
2015-12-18 20:33:38 +00:00
|
|
|
if !strings.Contains(err.Error(), "found a port label collision") {
|
2015-09-26 01:59:17 +00:00
|
|
|
t.Fatalf("Expected collision error; got %v", err)
|
|
|
|
}
|
2015-09-23 20:44:08 +00:00
|
|
|
}
|
2015-11-18 01:06:29 +00:00
|
|
|
|
2016-03-10 18:16:35 +00:00
|
|
|
func TestIncorrectKey(t *testing.T) {
|
|
|
|
path, err := filepath.Abs(filepath.Join("./test-fixtures", "basic_wrong_key.hcl"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Can't get absolute path for file: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = ParseFile(path)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Expected an error")
|
|
|
|
}
|
|
|
|
|
2017-02-22 20:30:05 +00:00
|
|
|
if !strings.Contains(err.Error(), "* group: 'binsl', task: 'binstore', service: 'foo', check -> invalid key: nterval") {
|
|
|
|
t.Fatalf("Expected key error; got %v", err)
|
2016-03-10 18:16:35 +00:00
|
|
|
}
|
|
|
|
}
|