From 9fe74c90f777d33446f1b66db91fc41eed2671d4 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Thu, 3 Sep 2020 06:34:04 -0500 Subject: [PATCH] Isolate the jobspec package from the rest of Nomad (#8815) This eases adoption of the jobspec package by other projects (e.g. terraform nomad provider, Lavant). Either by consuming directy as a library (hopefully without having go mod import rest of nomad) or by copying the package without modification. Ideally, this package will be published as an independent module. We aren't ready for that considering we'll be switching to HCLv2 "soon", but eitherway, this seems like a reasonable intermediate step if we choose to. --- jobspec/helper.go | 113 ++++++++ jobspec/helper_test.go | 24 ++ jobspec/parse.go | 19 +- jobspec/parse_group.go | 17 +- jobspec/parse_job.go | 17 +- jobspec/parse_multiregion.go | 7 +- jobspec/parse_network.go | 7 +- jobspec/parse_service.go | 31 +- jobspec/parse_task.go | 29 +- jobspec/parse_test.go | 536 ++++++++++++++++++----------------- 10 files changed, 470 insertions(+), 330 deletions(-) create mode 100644 jobspec/helper.go create mode 100644 jobspec/helper_test.go diff --git a/jobspec/helper.go b/jobspec/helper.go new file mode 100644 index 000000000000..99bf80f830f1 --- /dev/null +++ b/jobspec/helper.go @@ -0,0 +1,113 @@ +package jobspec + +// These functions are copied from helper/funcs.go +// added here to avoid jobspec depending on any other package + +import ( + "fmt" + "reflect" + "strings" + "time" + + multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/hcl/hcl/ast" +) + +// stringToPtr returns the pointer to a string +func stringToPtr(str string) *string { + return &str +} + +// timeToPtr returns the pointer to a time.Duration. +func timeToPtr(t time.Duration) *time.Duration { + return &t +} + +// boolToPtr returns the pointer to a boolean +func boolToPtr(b bool) *bool { + return &b +} + +func checkHCLKeys(node ast.Node, valid []string) error { + var list *ast.ObjectList + switch n := node.(type) { + case *ast.ObjectList: + list = n + case *ast.ObjectType: + list = n.List + default: + return fmt.Errorf("cannot check HCL keys of type %T", n) + } + + validMap := make(map[string]struct{}, len(valid)) + for _, v := range valid { + validMap[v] = struct{}{} + } + + var result error + for _, item := range list.Items { + key := item.Keys[0].Token.Value().(string) + if _, ok := validMap[key]; !ok { + result = multierror.Append(result, fmt.Errorf( + "invalid key: %s", key)) + } + } + + return result +} + +// UnusedKeys returns a pretty-printed error if any `hcl:",unusedKeys"` is not empty +func unusedKeys(obj interface{}) error { + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { + val = reflect.Indirect(val) + } + return unusedKeysImpl([]string{}, val) +} + +func unusedKeysImpl(path []string, val reflect.Value) error { + stype := val.Type() + for i := 0; i < stype.NumField(); i++ { + ftype := stype.Field(i) + fval := val.Field(i) + tags := strings.Split(ftype.Tag.Get("hcl"), ",") + name := tags[0] + tags = tags[1:] + + if fval.Kind() == reflect.Ptr { + fval = reflect.Indirect(fval) + } + + // struct? recurse. Add the struct's key to the path + if fval.Kind() == reflect.Struct { + err := unusedKeysImpl(append([]string{name}, path...), fval) + if err != nil { + return err + } + continue + } + + // Search the hcl tags for "unusedKeys" + unusedKeys := false + for _, p := range tags { + if p == "unusedKeys" { + unusedKeys = true + break + } + } + + if unusedKeys { + ks, ok := fval.Interface().([]string) + if ok && len(ks) != 0 { + ps := "" + if len(path) > 0 { + ps = strings.Join(path, ".") + " " + } + return fmt.Errorf("%sunexpected keys %s", + ps, + strings.Join(ks, ", ")) + } + } + } + return nil +} diff --git a/jobspec/helper_test.go b/jobspec/helper_test.go new file mode 100644 index 000000000000..f7854c80195b --- /dev/null +++ b/jobspec/helper_test.go @@ -0,0 +1,24 @@ +package jobspec + +// These functions are copied from helper/funcs.go +// added here to avoid jobspec depending on any other package + +// intToPtr returns the pointer to an int +func intToPtr(i int) *int { + return &i +} + +// int8ToPtr returns the pointer to an int8 +func int8ToPtr(i int8) *int8 { + return &i +} + +// int64ToPtr returns the pointer to an int +func int64ToPtr(i int64) *int64 { + return &i +} + +// Uint64ToPtr returns the pointer to an uint64 +func uint64ToPtr(u uint64) *uint64 { + return &u +} diff --git a/jobspec/parse.go b/jobspec/parse.go index f6e7b8584c8c..140660463416 100644 --- a/jobspec/parse.go +++ b/jobspec/parse.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -48,7 +47,7 @@ func Parse(r io.Reader) (*api.Job, error) { valid := []string{ "job", } - if err := helper.CheckHCLKeys(list, valid); err != nil { + if err := checkHCLKeys(list, valid); err != nil { return nil, err } @@ -100,7 +99,7 @@ func parseReschedulePolicy(final **api.ReschedulePolicy, list *ast.ObjectList) e "max_delay", "delay_function", } - if err := helper.CheckHCLKeys(obj.Val, valid); err != nil { + if err := checkHCLKeys(obj.Val, valid); err != nil { return err } @@ -140,7 +139,7 @@ func parseConstraints(result *[]*api.Constraint, list *ast.ObjectList) error { "version", "semver", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -230,7 +229,7 @@ func parseAffinities(result *[]*api.Affinity, list *ast.ObjectList) error { "semver", "weight", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -307,7 +306,7 @@ func parseSpread(result *[]*api.Spread, list *ast.ObjectList) error { "weight", "target", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -370,7 +369,7 @@ func parseSpreadTarget(result *[]*api.SpreadTarget, list *ast.ObjectList) error "percent", "value", } - if err := helper.CheckHCLKeys(listVal, valid); err != nil { + if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, fmt.Sprintf("'%s' ->", n)) } @@ -433,7 +432,7 @@ func parseUpdate(result **api.UpdateStrategy, list *ast.ObjectList) error { "auto_promote", "canary", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -469,7 +468,7 @@ func parseMigrate(result **api.MigrateStrategy, list *ast.ObjectList) error { "min_healthy_time", "healthy_deadline", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -512,7 +511,7 @@ func parseVault(result *api.Vault, list *ast.ObjectList) error { "change_mode", "change_signal", } - if err := helper.CheckHCLKeys(listVal, valid); err != nil { + if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, "vault ->") } diff --git a/jobspec/parse_group.go b/jobspec/parse_group.go index d5a495c64534..2514d639e5cc 100644 --- a/jobspec/parse_group.go +++ b/jobspec/parse_group.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -58,7 +57,7 @@ func parseGroups(result *api.Job, list *ast.ObjectList) error { "scaling", "stop_after_client_disconnect", } - if err := helper.CheckHCLKeys(listVal, valid); err != nil { + if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, fmt.Sprintf("'%s' ->", n)) } @@ -84,7 +83,7 @@ func parseGroups(result *api.Job, list *ast.ObjectList) error { // Build the group with the basic decode var g api.TaskGroup - g.Name = helper.StringToPtr(n) + g.Name = stringToPtr(n) dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, @@ -201,8 +200,8 @@ func parseGroups(result *api.Job, list *ast.ObjectList) error { // If we have a vault block, then parse that if o := listVal.Filter("vault"); len(o.Items) > 0 { tgVault := &api.Vault{ - Env: helper.BoolToPtr(true), - ChangeMode: helper.StringToPtr("restart"), + Env: boolToPtr(true), + ChangeMode: stringToPtr("restart"), } if err := parseVault(tgVault, o); err != nil { @@ -244,7 +243,7 @@ func parseEphemeralDisk(result **api.EphemeralDisk, list *ast.ObjectList) error "size", "migrate", } - if err := helper.CheckHCLKeys(obj.Val, valid); err != nil { + if err := checkHCLKeys(obj.Val, valid); err != nil { return err } @@ -278,7 +277,7 @@ func parseRestartPolicy(final **api.RestartPolicy, list *ast.ObjectList) error { "delay", "mode", } - if err := helper.CheckHCLKeys(obj.Val, valid); err != nil { + if err := checkHCLKeys(obj.Val, valid); err != nil { return err } @@ -308,7 +307,7 @@ func parseVolumes(out *map[string]*api.VolumeRequest, list *ast.ObjectList) erro hcl.DecodeObject(out, list) for k, v := range *out { - err := helper.UnusedKeys(v) + err := unusedKeys(v) if err != nil { return err } @@ -343,7 +342,7 @@ func parseScalingPolicy(out **api.ScalingPolicy, list *ast.ObjectList) error { "policy", "enabled", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } diff --git a/jobspec/parse_job.go b/jobspec/parse_job.go index e9143b036312..b59b3b594565 100644 --- a/jobspec/parse_job.go +++ b/jobspec/parse_job.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -41,8 +40,8 @@ func parseJob(result *api.Job, list *ast.ObjectList) error { delete(m, "multiregion") // Set the ID and name to the object key - result.ID = helper.StringToPtr(obj.Keys[0].Token.Value().(string)) - result.Name = helper.StringToPtr(*result.ID) + result.ID = stringToPtr(obj.Keys[0].Token.Value().(string)) + result.Name = stringToPtr(*result.ID) // Decode the rest if err := mapstructure.WeakDecode(m, result); err != nil { @@ -83,7 +82,7 @@ func parseJob(result *api.Job, list *ast.ObjectList) error { "consul_token", "multiregion", } - if err := helper.CheckHCLKeys(listVal, valid); err != nil { + if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, "job:") } @@ -176,7 +175,7 @@ func parseJob(result *api.Job, list *ast.ObjectList) error { result.TaskGroups = make([]*api.TaskGroup, len(tasks), len(tasks)*2) for i, t := range tasks { result.TaskGroups[i] = &api.TaskGroup{ - Name: helper.StringToPtr(t.Name), + Name: stringToPtr(t.Name), Tasks: []*api.Task{t}, } } @@ -192,8 +191,8 @@ func parseJob(result *api.Job, list *ast.ObjectList) error { // If we have a vault block, then parse that if o := listVal.Filter("vault"); len(o.Items) > 0 { jobVault := &api.Vault{ - Env: helper.BoolToPtr(true), - ChangeMode: helper.StringToPtr("restart"), + Env: boolToPtr(true), + ChangeMode: stringToPtr("restart"), } if err := parseVault(jobVault, o); err != nil { @@ -234,7 +233,7 @@ func parsePeriodic(result **api.PeriodicConfig, list *ast.ObjectList) error { "prohibit_overlap", "time_zone", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -281,7 +280,7 @@ func parseParameterizedJob(result **api.ParameterizedJobConfig, list *ast.Object "meta_required", "meta_optional", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } diff --git a/jobspec/parse_multiregion.go b/jobspec/parse_multiregion.go index c0e0ed068821..76bed28b1ac1 100644 --- a/jobspec/parse_multiregion.go +++ b/jobspec/parse_multiregion.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -41,7 +40,7 @@ func parseMultiregion(result *api.Multiregion, list *ast.ObjectList) error { "strategy", "region", } - if err := helper.CheckHCLKeys(obj.Val, valid); err != nil { + if err := checkHCLKeys(obj.Val, valid); err != nil { return err } @@ -76,7 +75,7 @@ func parseMultiregionStrategy(final **api.MultiregionStrategy, list *ast.ObjectL "max_parallel", "on_failure", } - if err := helper.CheckHCLKeys(obj.Val, valid); err != nil { + if err := checkHCLKeys(obj.Val, valid); err != nil { return err } @@ -133,7 +132,7 @@ func parseMultiregionRegions(result *api.Multiregion, list *ast.ObjectList) erro "datacenters", "meta", } - if err := helper.CheckHCLKeys(listVal, valid); err != nil { + if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, fmt.Sprintf("'%s' ->", n)) } diff --git a/jobspec/parse_network.go b/jobspec/parse_network.go index 16a2e13451c4..6b7e9474e8d8 100644 --- a/jobspec/parse_network.go +++ b/jobspec/parse_network.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -25,7 +24,7 @@ func ParseNetwork(o *ast.ObjectList) (*api.NetworkResource, error) { "dns", "port", } - if err := helper.CheckHCLKeys(o.Items[0].Val, valid); err != nil { + if err := checkHCLKeys(o.Items[0].Val, valid); err != nil { return nil, multierror.Prefix(err, "network ->") } @@ -81,7 +80,7 @@ func parsePorts(networkObj *ast.ObjectList, nw *api.NetworkResource) error { "to", "host_network", } - if err := helper.CheckHCLKeys(port.Val, valid); err != nil { + if err := checkHCLKeys(port.Val, valid); err != nil { return err } @@ -119,7 +118,7 @@ func parseDNS(dns *ast.ObjectItem) (*api.DNSConfig, error) { "options", } - if err := helper.CheckHCLKeys(dns.Val, valid); err != nil { + if err := checkHCLKeys(dns.Val, valid); err != nil { return nil, multierror.Prefix(err, "dns ->") } diff --git a/jobspec/parse_service.go b/jobspec/parse_service.go index 95f9b3ad75c0..73fdac41fb32 100644 --- a/jobspec/parse_service.go +++ b/jobspec/parse_service.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -51,7 +50,7 @@ func parseService(o *ast.ObjectItem) (*api.Service, error) { "meta", "canary_meta", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, err } @@ -151,7 +150,7 @@ func parseConnect(co *ast.ObjectItem) (*api.ConsulConnect, error) { "sidecar_task", } - if err := helper.CheckHCLKeys(co.Val, valid); err != nil { + if err := checkHCLKeys(co.Val, valid); err != nil { return nil, multierror.Prefix(err, "connect ->") } @@ -227,7 +226,7 @@ func parseGateway(o *ast.ObjectItem) (*api.ConsulGateway, error) { "ingress", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "gateway ->") } @@ -299,7 +298,7 @@ func parseGatewayProxy(o *ast.ObjectItem) (*api.ConsulGatewayProxy, error) { "config", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "proxy ->") } @@ -385,7 +384,7 @@ func parseConsulIngressService(o *ast.ObjectItem) (*api.ConsulIngressService, er "hosts", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "service ->") } @@ -416,7 +415,7 @@ func parseConsulIngressListener(o *ast.ObjectItem) (*api.ConsulIngressListener, "service", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "listener ->") } @@ -467,7 +466,7 @@ func parseConsulGatewayTLS(o *ast.ObjectItem) (*api.ConsulGatewayTLSConfig, erro "enabled", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "tls ->") } @@ -497,7 +496,7 @@ func parseIngressConfigEntry(o *ast.ObjectItem) (*api.ConsulIngressConfigEntry, "listener", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "ingress ->") } @@ -551,7 +550,7 @@ func parseSidecarService(o *ast.ObjectItem) (*api.ConsulSidecarService, error) { "tags", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "sidecar_service ->") } @@ -653,7 +652,7 @@ func parseProxy(o *ast.ObjectItem) (*api.ConsulProxy, error) { "config", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return nil, multierror.Prefix(err, "proxy ->") } @@ -738,7 +737,7 @@ func parseExpose(eo *ast.ObjectItem) (*api.ConsulExposeConfig, error) { "path", // an array of path blocks } - if err := helper.CheckHCLKeys(eo.Val, valid); err != nil { + if err := checkHCLKeys(eo.Val, valid); err != nil { return nil, multierror.Prefix(err, "expose ->") } @@ -776,7 +775,7 @@ func parseExposePath(epo *ast.ObjectItem) (*api.ConsulExposePath, error) { "listener_port", } - if err := helper.CheckHCLKeys(epo.Val, valid); err != nil { + if err := checkHCLKeys(epo.Val, valid); err != nil { return nil, multierror.Prefix(err, "path ->") } @@ -806,7 +805,7 @@ func parseUpstream(uo *ast.ObjectItem) (*api.ConsulUpstream, error) { "local_bind_port", } - if err := helper.CheckHCLKeys(uo.Val, valid); err != nil { + if err := checkHCLKeys(uo.Val, valid); err != nil { return nil, multierror.Prefix(err, "upstream ->") } @@ -859,7 +858,7 @@ func parseChecks(service *api.Service, checkObjs *ast.ObjectList) error { "success_before_passing", "failures_before_critical", } - if err := helper.CheckHCLKeys(co.Val, valid); err != nil { + if err := checkHCLKeys(co.Val, valid); err != nil { return multierror.Prefix(err, "check ->") } @@ -945,7 +944,7 @@ func parseCheckRestart(cro *ast.ObjectItem) (*api.CheckRestart, error) { "ignore_warnings", } - if err := helper.CheckHCLKeys(cro.Val, valid); err != nil { + if err := checkHCLKeys(cro.Val, valid); err != nil { return nil, multierror.Prefix(err, "check_restart ->") } diff --git a/jobspec/parse_task.go b/jobspec/parse_task.go index 2a1ebc60b764..07d02614519e 100644 --- a/jobspec/parse_task.go +++ b/jobspec/parse_task.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/hcl" "github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" "github.com/mitchellh/mapstructure" ) @@ -87,7 +86,7 @@ func parseTask(item *ast.ObjectItem, keys []string) (*api.Task, error) { } // Check for invalid keys - if err := helper.CheckHCLKeys(listVal, keys); err != nil { + if err := checkHCLKeys(listVal, keys); err != nil { return nil, err } @@ -247,7 +246,7 @@ func parseTask(item *ast.ObjectItem, keys []string) (*api.Task, error) { "max_files", "max_file_size", } - if err := helper.CheckHCLKeys(logsBlock.Val, valid); err != nil { + if err := checkHCLKeys(logsBlock.Val, valid); err != nil { return nil, multierror.Prefix(err, "logs ->") } @@ -280,8 +279,8 @@ func parseTask(item *ast.ObjectItem, keys []string) (*api.Task, error) { // If we have a vault block, then parse that if o := listVal.Filter("vault"); len(o.Items) > 0 { v := &api.Vault{ - Env: helper.BoolToPtr(true), - ChangeMode: helper.StringToPtr("restart"), + Env: boolToPtr(true), + ChangeMode: stringToPtr("restart"), } if err := parseVault(v, o); err != nil { @@ -303,7 +302,7 @@ func parseTask(item *ast.ObjectItem, keys []string) (*api.Task, error) { valid := []string{ "file", } - if err := helper.CheckHCLKeys(dispatchBlock.Val, valid); err != nil { + if err := checkHCLKeys(dispatchBlock.Val, valid); err != nil { return nil, multierror.Prefix(err, "dispatch_payload ->") } @@ -331,7 +330,7 @@ func parseTask(item *ast.ObjectItem, keys []string) (*api.Task, error) { "hook", "sidecar", } - if err := helper.CheckHCLKeys(lifecycleBlock.Val, valid); err != nil { + if err := checkHCLKeys(lifecycleBlock.Val, valid); err != nil { return nil, multierror.Prefix(err, "lifecycle ->") } @@ -356,7 +355,7 @@ func parseArtifacts(result *[]*api.TaskArtifact, list *ast.ObjectList) error { "mode", "destination", } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -430,7 +429,7 @@ func parseTemplates(result *[]*api.Template, list *ast.ObjectList) error { "env", "vault_grace", //COMPAT(0.12) not used; emits warning in 0.11. } - if err := helper.CheckHCLKeys(o.Val, valid); err != nil { + if err := checkHCLKeys(o.Val, valid); err != nil { return err } @@ -440,9 +439,9 @@ func parseTemplates(result *[]*api.Template, list *ast.ObjectList) error { } templ := &api.Template{ - ChangeMode: helper.StringToPtr("restart"), - Splay: helper.TimeToPtr(5 * time.Second), - Perms: helper.StringToPtr("0644"), + ChangeMode: stringToPtr("restart"), + Splay: timeToPtr(5 * time.Second), + Perms: stringToPtr("0644"), } dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ @@ -492,7 +491,7 @@ func parseResources(result *api.Resources, list *ast.ObjectList) error { "network", "device", } - if err := helper.CheckHCLKeys(listVal, valid); err != nil { + if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, "resources ->") } @@ -542,7 +541,7 @@ func parseResources(result *api.Resources, list *ast.ObjectList) error { "affinity", "constraint", } - if err := helper.CheckHCLKeys(do.Val, valid); err != nil { + if err := checkHCLKeys(do.Val, valid); err != nil { return multierror.Prefix(err, fmt.Sprintf("resources, device[%d]->", idx)) } @@ -593,7 +592,7 @@ func parseVolumeMounts(out *[]*api.VolumeMount, list *ast.ObjectList) error { "destination", "propagation_mode", } - if err := helper.CheckHCLKeys(item.Val, valid); err != nil { + if err := checkHCLKeys(item.Val, valid); err != nil { return err } diff --git a/jobspec/parse_test.go b/jobspec/parse_test.go index 05af3a655b0f..ad3b2e3bc4f5 100644 --- a/jobspec/parse_test.go +++ b/jobspec/parse_test.go @@ -9,11 +9,21 @@ import ( capi "github.com/hashicorp/consul/api" "github.com/hashicorp/nomad/api" - "github.com/hashicorp/nomad/helper" - "github.com/hashicorp/nomad/nomad/structs" "github.com/kr/pretty" ) +// consts copied from nomad/structs package to keep jobspec isolated from rest of nomad +const ( + // vaultChangeModeRestart restarts the task when a new token is retrieved. + vaultChangeModeRestart = "restart" + + // vaultChangeModeSignal signals the task when a new token is retrieved. + vaultChangeModeSignal = "signal" + + // templateChangeModeRestart marks that the task should be restarted if the + templateChangeModeRestart = "restart" +) + func TestParse(t *testing.T) { cases := []struct { File string @@ -23,16 +33,16 @@ func TestParse(t *testing.T) { { "basic.hcl", &api.Job{ - ID: helper.StringToPtr("binstore-storagelocker"), - Name: helper.StringToPtr("binstore-storagelocker"), - Type: helper.StringToPtr("batch"), - Priority: helper.IntToPtr(52), - AllAtOnce: helper.BoolToPtr(true), + ID: stringToPtr("binstore-storagelocker"), + Name: stringToPtr("binstore-storagelocker"), + Type: stringToPtr("batch"), + Priority: intToPtr(52), + AllAtOnce: boolToPtr(true), Datacenters: []string{"us2", "eu1"}, - Region: helper.StringToPtr("fooregion"), - Namespace: helper.StringToPtr("foonamespace"), - ConsulToken: helper.StringToPtr("abc"), - VaultToken: helper.StringToPtr("foo"), + Region: stringToPtr("fooregion"), + Namespace: stringToPtr("foonamespace"), + ConsulToken: stringToPtr("abc"), + VaultToken: stringToPtr("foo"), Meta: map[string]string{ "foo": "bar", @@ -56,14 +66,14 @@ func TestParse(t *testing.T) { LTarget: "${meta.team}", RTarget: "mobile", Operand: "=", - Weight: helper.Int8ToPtr(50), + Weight: int8ToPtr(50), }, }, Spreads: []*api.Spread{ { Attribute: "${meta.rack}", - Weight: helper.Int8ToPtr(100), + Weight: int8ToPtr(100), SpreadTarget: []*api.SpreadTarget{ { Value: "r1", @@ -78,20 +88,20 @@ func TestParse(t *testing.T) { }, Update: &api.UpdateStrategy{ - Stagger: helper.TimeToPtr(60 * time.Second), - MaxParallel: helper.IntToPtr(2), - HealthCheck: helper.StringToPtr("manual"), - MinHealthyTime: helper.TimeToPtr(10 * time.Second), - HealthyDeadline: helper.TimeToPtr(10 * time.Minute), - ProgressDeadline: helper.TimeToPtr(10 * time.Minute), - AutoRevert: helper.BoolToPtr(true), - AutoPromote: helper.BoolToPtr(true), - Canary: helper.IntToPtr(1), + Stagger: timeToPtr(60 * time.Second), + MaxParallel: intToPtr(2), + HealthCheck: stringToPtr("manual"), + MinHealthyTime: timeToPtr(10 * time.Second), + HealthyDeadline: timeToPtr(10 * time.Minute), + ProgressDeadline: timeToPtr(10 * time.Minute), + AutoRevert: boolToPtr(true), + AutoPromote: boolToPtr(true), + Canary: intToPtr(1), }, TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("outside"), + Name: stringToPtr("outside"), Tasks: []*api.Task{ { @@ -108,8 +118,8 @@ func TestParse(t *testing.T) { }, { - Name: helper.StringToPtr("binsl"), - Count: helper.IntToPtr(5), + Name: stringToPtr("binsl"), + Count: intToPtr(5), Constraints: []*api.Constraint{ { LTarget: "kernel.os", @@ -150,7 +160,7 @@ func TestParse(t *testing.T) { LTarget: "${node.datacenter}", RTarget: "dc2", Operand: "=", - Weight: helper.Int8ToPtr(100), + Weight: int8ToPtr(100), }, }, Meta: map[string]string{ @@ -159,15 +169,15 @@ func TestParse(t *testing.T) { "elb_checks": "3", }, RestartPolicy: &api.RestartPolicy{ - Interval: helper.TimeToPtr(10 * time.Minute), - Attempts: helper.IntToPtr(5), - Delay: helper.TimeToPtr(15 * time.Second), - Mode: helper.StringToPtr("delay"), + Interval: timeToPtr(10 * time.Minute), + Attempts: intToPtr(5), + Delay: timeToPtr(15 * time.Second), + Mode: stringToPtr("delay"), }, Spreads: []*api.Spread{ { Attribute: "${node.datacenter}", - Weight: helper.Int8ToPtr(50), + Weight: int8ToPtr(50), SpreadTarget: []*api.SpreadTarget{ { Value: "dc1", @@ -184,30 +194,30 @@ func TestParse(t *testing.T) { }, }, }, - StopAfterClientDisconnect: helper.TimeToPtr(120 * time.Second), + StopAfterClientDisconnect: timeToPtr(120 * time.Second), ReschedulePolicy: &api.ReschedulePolicy{ - Interval: helper.TimeToPtr(12 * time.Hour), - Attempts: helper.IntToPtr(5), + Interval: timeToPtr(12 * time.Hour), + Attempts: intToPtr(5), }, EphemeralDisk: &api.EphemeralDisk{ - Sticky: helper.BoolToPtr(true), - SizeMB: helper.IntToPtr(150), + Sticky: boolToPtr(true), + SizeMB: intToPtr(150), }, Update: &api.UpdateStrategy{ - MaxParallel: helper.IntToPtr(3), - HealthCheck: helper.StringToPtr("checks"), - MinHealthyTime: helper.TimeToPtr(1 * time.Second), - HealthyDeadline: helper.TimeToPtr(1 * time.Minute), - ProgressDeadline: helper.TimeToPtr(1 * time.Minute), - AutoRevert: helper.BoolToPtr(false), - AutoPromote: helper.BoolToPtr(false), - Canary: helper.IntToPtr(2), + MaxParallel: intToPtr(3), + HealthCheck: stringToPtr("checks"), + MinHealthyTime: timeToPtr(1 * time.Second), + HealthyDeadline: timeToPtr(1 * time.Minute), + ProgressDeadline: timeToPtr(1 * time.Minute), + AutoRevert: boolToPtr(false), + AutoPromote: boolToPtr(false), + Canary: intToPtr(2), }, Migrate: &api.MigrateStrategy{ - MaxParallel: helper.IntToPtr(2), - HealthCheck: helper.StringToPtr("task_states"), - MinHealthyTime: helper.TimeToPtr(11 * time.Second), - HealthyDeadline: helper.TimeToPtr(11 * time.Minute), + MaxParallel: intToPtr(2), + HealthCheck: stringToPtr("task_states"), + MinHealthyTime: timeToPtr(11 * time.Second), + HealthyDeadline: timeToPtr(11 * time.Minute), }, Tasks: []*api.Task{ { @@ -225,8 +235,8 @@ func TestParse(t *testing.T) { }, VolumeMounts: []*api.VolumeMount{ { - Volume: helper.StringToPtr("foo"), - Destination: helper.StringToPtr("/mnt/foo"), + Volume: stringToPtr("foo"), + Destination: stringToPtr("/mnt/foo"), }, }, Affinities: []*api.Affinity{ @@ -234,11 +244,11 @@ func TestParse(t *testing.T) { LTarget: "${meta.foo}", RTarget: "a,b,c", Operand: "set_contains", - Weight: helper.Int8ToPtr(25), + Weight: int8ToPtr(25), }, }, RestartPolicy: &api.RestartPolicy{ - Attempts: helper.IntToPtr(10), + Attempts: intToPtr(10), }, Services: []*api.Service{ { @@ -262,7 +272,7 @@ func TestParse(t *testing.T) { GRPCUseTLS: true, CheckRestart: &api.CheckRestart{ Limit: 3, - Grace: helper.TimeToPtr(10 * time.Second), + Grace: timeToPtr(10 * time.Second), IgnoreWarnings: true, }, }, @@ -274,11 +284,11 @@ func TestParse(t *testing.T) { "LOREM": "ipsum", }, Resources: &api.Resources{ - CPU: helper.IntToPtr(500), - MemoryMB: helper.IntToPtr(128), + CPU: intToPtr(500), + MemoryMB: intToPtr(128), Networks: []*api.NetworkResource{ { - MBits: helper.IntToPtr(100), + MBits: intToPtr(100), 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}}, }, @@ -286,7 +296,7 @@ func TestParse(t *testing.T) { Devices: []*api.RequestedDevice{ { Name: "nvidia/gpu", - Count: helper.Uint64ToPtr(10), + Count: uint64ToPtr(10), Constraints: []*api.Constraint{ { LTarget: "${device.attr.memory}", @@ -299,7 +309,7 @@ func TestParse(t *testing.T) { LTarget: "${device.model}", RTarget: "1080ti", Operand: "=", - Weight: helper.Int8ToPtr(50), + Weight: int8ToPtr(50), }, }, }, @@ -309,53 +319,53 @@ func TestParse(t *testing.T) { }, }, }, - KillTimeout: helper.TimeToPtr(22 * time.Second), + KillTimeout: timeToPtr(22 * time.Second), ShutdownDelay: 11 * time.Second, LogConfig: &api.LogConfig{ - MaxFiles: helper.IntToPtr(14), - MaxFileSizeMB: helper.IntToPtr(101), + MaxFiles: intToPtr(14), + MaxFileSizeMB: intToPtr(101), }, Artifacts: []*api.TaskArtifact{ { - GetterSource: helper.StringToPtr("http://foo.com/artifact"), + GetterSource: stringToPtr("http://foo.com/artifact"), GetterOptions: map[string]string{ "checksum": "md5:b8a4f3f72ecab0510a6a31e997461c5f", }, }, { - GetterSource: helper.StringToPtr("http://bar.com/artifact"), - RelativeDest: helper.StringToPtr("test/foo/"), + GetterSource: stringToPtr("http://bar.com/artifact"), + RelativeDest: stringToPtr("test/foo/"), GetterOptions: map[string]string{ "checksum": "md5:ff1cc0d3432dad54d607c1505fb7245c", }, - GetterMode: helper.StringToPtr("file"), + GetterMode: stringToPtr("file"), }, }, Vault: &api.Vault{ - Namespace: helper.StringToPtr("ns1"), + Namespace: stringToPtr("ns1"), Policies: []string{"foo", "bar"}, - Env: helper.BoolToPtr(true), - ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), + Env: boolToPtr(true), + ChangeMode: stringToPtr(vaultChangeModeRestart), }, Templates: []*api.Template{ { - 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"), - Envvars: helper.BoolToPtr(true), - VaultGrace: helper.TimeToPtr(33 * time.Second), + SourcePath: stringToPtr("foo"), + DestPath: stringToPtr("foo"), + ChangeMode: stringToPtr("foo"), + ChangeSignal: stringToPtr("foo"), + Splay: timeToPtr(10 * time.Second), + Perms: stringToPtr("0644"), + Envvars: boolToPtr(true), + VaultGrace: timeToPtr(33 * time.Second), }, { - 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("__"), + SourcePath: stringToPtr("bar"), + DestPath: stringToPtr("bar"), + ChangeMode: stringToPtr(templateChangeModeRestart), + Splay: timeToPtr(5 * time.Second), + Perms: stringToPtr("777"), + LeftDelim: stringToPtr("--"), + RightDelim: stringToPtr("__"), }, }, Leader: true, @@ -373,8 +383,8 @@ func TestParse(t *testing.T) { "image": "hashicorp/storagelocker", }, Resources: &api.Resources{ - CPU: helper.IntToPtr(500), - MemoryMB: helper.IntToPtr(128), + CPU: intToPtr(500), + MemoryMB: intToPtr(128), }, Constraints: []*api.Constraint{ { @@ -385,9 +395,9 @@ func TestParse(t *testing.T) { }, Vault: &api.Vault{ Policies: []string{"foo", "bar"}, - Env: helper.BoolToPtr(false), - ChangeMode: helper.StringToPtr(structs.VaultChangeModeSignal), - ChangeSignal: helper.StringToPtr("SIGUSR1"), + Env: boolToPtr(false), + ChangeMode: stringToPtr(vaultChangeModeSignal), + ChangeSignal: stringToPtr("SIGUSR1"), }, }, }, @@ -418,8 +428,8 @@ func TestParse(t *testing.T) { { "default-job.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), }, false, }, @@ -427,13 +437,13 @@ func TestParse(t *testing.T) { { "version-constraint.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Constraints: []*api.Constraint{ { LTarget: "$attr.kernel.version", RTarget: "~> 3.2", - Operand: structs.ConstraintVersion, + Operand: api.ConstraintVersion, }, }, }, @@ -443,13 +453,13 @@ func TestParse(t *testing.T) { { "regexp-constraint.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Constraints: []*api.Constraint{ { LTarget: "$attr.kernel.version", RTarget: "[0-9.]+", - Operand: structs.ConstraintRegex, + Operand: api.ConstraintRegex, }, }, }, @@ -459,13 +469,13 @@ func TestParse(t *testing.T) { { "set-contains-constraint.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Constraints: []*api.Constraint{ { LTarget: "$meta.data", RTarget: "foo,bar,baz", - Operand: structs.ConstraintSetContains, + Operand: api.ConstraintSetContains, }, }, }, @@ -475,11 +485,11 @@ func TestParse(t *testing.T) { { "distinctHosts-constraint.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Constraints: []*api.Constraint{ { - Operand: structs.ConstraintDistinctHosts, + Operand: api.ConstraintDistinctHosts, }, }, }, @@ -489,11 +499,11 @@ func TestParse(t *testing.T) { { "distinctProperty-constraint.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Constraints: []*api.Constraint{ { - Operand: structs.ConstraintDistinctProperty, + Operand: api.ConstraintDistinctProperty, LTarget: "${meta.rack}", }, }, @@ -504,13 +514,13 @@ func TestParse(t *testing.T) { { "periodic-cron.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Periodic: &api.PeriodicConfig{ - SpecType: helper.StringToPtr(api.PeriodicSpecCron), - Spec: helper.StringToPtr("*/5 * * *"), - ProhibitOverlap: helper.BoolToPtr(true), - TimeZone: helper.StringToPtr("Europe/Minsk"), + SpecType: stringToPtr(api.PeriodicSpecCron), + Spec: stringToPtr("*/5 * * *"), + ProhibitOverlap: boolToPtr(true), + TimeZone: stringToPtr("Europe/Minsk"), }, }, false, @@ -519,8 +529,8 @@ func TestParse(t *testing.T) { { "specify-job.hcl", &api.Job{ - ID: helper.StringToPtr("job1"), - Name: helper.StringToPtr("My Job"), + ID: stringToPtr("job1"), + Name: stringToPtr("My Job"), }, false, }, @@ -528,11 +538,11 @@ func TestParse(t *testing.T) { { "task-nested-config.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("bar"), + Name: stringToPtr("bar"), Tasks: []*api.Task{ { Name: "bar", @@ -562,30 +572,30 @@ func TestParse(t *testing.T) { { "artifacts.hcl", &api.Job{ - ID: helper.StringToPtr("binstore-storagelocker"), - Name: helper.StringToPtr("binstore-storagelocker"), + ID: stringToPtr("binstore-storagelocker"), + Name: stringToPtr("binstore-storagelocker"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("binsl"), + Name: stringToPtr("binsl"), Tasks: []*api.Task{ { Name: "binstore", Driver: "docker", Artifacts: []*api.TaskArtifact{ { - GetterSource: helper.StringToPtr("http://foo.com/bar"), + GetterSource: stringToPtr("http://foo.com/bar"), GetterOptions: map[string]string{"foo": "bar"}, - RelativeDest: helper.StringToPtr(""), + RelativeDest: stringToPtr(""), }, { - GetterSource: helper.StringToPtr("http://foo.com/baz"), + GetterSource: stringToPtr("http://foo.com/baz"), GetterOptions: nil, RelativeDest: nil, }, { - GetterSource: helper.StringToPtr("http://foo.com/bam"), + GetterSource: stringToPtr("http://foo.com/bam"), GetterOptions: nil, - RelativeDest: helper.StringToPtr("var/foo"), + RelativeDest: stringToPtr("var/foo"), }, }, }, @@ -598,11 +608,11 @@ func TestParse(t *testing.T) { { "csi-plugin.hcl", &api.Job{ - ID: helper.StringToPtr("binstore-storagelocker"), - Name: helper.StringToPtr("binstore-storagelocker"), + ID: stringToPtr("binstore-storagelocker"), + Name: stringToPtr("binstore-storagelocker"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("binsl"), + Name: stringToPtr("binsl"), Tasks: []*api.Task{ { Name: "binstore", @@ -622,13 +632,13 @@ func TestParse(t *testing.T) { { "service-check-initial-status.hcl", &api.Job{ - ID: helper.StringToPtr("check_initial_status"), - Name: helper.StringToPtr("check_initial_status"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("check_initial_status"), + Name: stringToPtr("check_initial_status"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), - Count: helper.IntToPtr(1), + Name: stringToPtr("group"), + Count: intToPtr(1), Tasks: []*api.Task{ { Name: "task", @@ -662,12 +672,12 @@ func TestParse(t *testing.T) { { "service-check-pass-fail.hcl", &api.Job{ - ID: helper.StringToPtr("check_pass_fail"), - Name: helper.StringToPtr("check_pass_fail"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("check_pass_fail"), + Name: stringToPtr("check_pass_fail"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), - Count: helper.IntToPtr(1), + Name: stringToPtr("group"), + Count: intToPtr(1), Tasks: []*api.Task{{ Name: "task", Services: []*api.Service{{ @@ -693,12 +703,12 @@ func TestParse(t *testing.T) { { "service-check-pass-fail.hcl", &api.Job{ - ID: helper.StringToPtr("check_pass_fail"), - Name: helper.StringToPtr("check_pass_fail"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("check_pass_fail"), + Name: stringToPtr("check_pass_fail"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), - Count: helper.IntToPtr(1), + Name: stringToPtr("group"), + Count: intToPtr(1), Tasks: []*api.Task{{ Name: "task", Services: []*api.Service{{ @@ -735,39 +745,39 @@ func TestParse(t *testing.T) { // TODO This should be pushed into the API "vault_inheritance.hcl", &api.Job{ - ID: helper.StringToPtr("example"), - Name: helper.StringToPtr("example"), + ID: stringToPtr("example"), + Name: stringToPtr("example"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("cache"), + Name: stringToPtr("cache"), Tasks: []*api.Task{ { Name: "redis", Vault: &api.Vault{ Policies: []string{"group"}, - Env: helper.BoolToPtr(true), - ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), + Env: boolToPtr(true), + ChangeMode: stringToPtr(vaultChangeModeRestart), }, }, { Name: "redis2", Vault: &api.Vault{ Policies: []string{"task"}, - Env: helper.BoolToPtr(false), - ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), + Env: boolToPtr(false), + ChangeMode: stringToPtr(vaultChangeModeRestart), }, }, }, }, { - Name: helper.StringToPtr("cache2"), + Name: stringToPtr("cache2"), Tasks: []*api.Task{ { Name: "redis", Vault: &api.Vault{ Policies: []string{"job"}, - Env: helper.BoolToPtr(true), - ChangeMode: helper.StringToPtr(structs.VaultChangeModeRestart), + Env: boolToPtr(true), + ChangeMode: stringToPtr(vaultChangeModeRestart), }, }, }, @@ -779,8 +789,8 @@ func TestParse(t *testing.T) { { "parameterized_job.hcl", &api.Job{ - ID: helper.StringToPtr("parameterized_job"), - Name: helper.StringToPtr("parameterized_job"), + ID: stringToPtr("parameterized_job"), + Name: stringToPtr("parameterized_job"), ParameterizedJob: &api.ParameterizedJobConfig{ Payload: "required", @@ -790,7 +800,7 @@ func TestParse(t *testing.T) { TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("foo"), + Name: stringToPtr("foo"), Tasks: []*api.Task{ { Name: "bar", @@ -808,11 +818,11 @@ func TestParse(t *testing.T) { { "job-with-kill-signal.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("bar"), + Name: stringToPtr("bar"), Tasks: []*api.Task{ { Name: "bar", @@ -831,12 +841,12 @@ func TestParse(t *testing.T) { { "service-check-driver-address.hcl", &api.Job{ - ID: helper.StringToPtr("address_mode_driver"), - Name: helper.StringToPtr("address_mode_driver"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("address_mode_driver"), + Name: stringToPtr("address_mode_driver"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Tasks: []*api.Task{ { Name: "task", @@ -879,12 +889,12 @@ func TestParse(t *testing.T) { { "service-check-restart.hcl", &api.Job{ - ID: helper.StringToPtr("service_check_restart"), - Name: helper.StringToPtr("service_check_restart"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("service_check_restart"), + Name: stringToPtr("service_check_restart"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Tasks: []*api.Task{ { Name: "task", @@ -893,7 +903,7 @@ func TestParse(t *testing.T) { Name: "http-service", CheckRestart: &api.CheckRestart{ Limit: 3, - Grace: helper.TimeToPtr(10 * time.Second), + Grace: timeToPtr(10 * time.Second), IgnoreWarnings: true, }, Checks: []api.ServiceCheck{ @@ -915,12 +925,12 @@ func TestParse(t *testing.T) { { "service-meta.hcl", &api.Job{ - ID: helper.StringToPtr("service_meta"), - Name: helper.StringToPtr("service_meta"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("service_meta"), + Name: stringToPtr("service_meta"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Tasks: []*api.Task{ { Name: "task", @@ -942,11 +952,11 @@ func TestParse(t *testing.T) { { "service-enable-tag-override.hcl", &api.Job{ - ID: helper.StringToPtr("service_eto"), - Name: helper.StringToPtr("service_eto"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("service_eto"), + Name: stringToPtr("service_eto"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Tasks: []*api.Task{{ Name: "task", Services: []*api.Service{{ @@ -961,20 +971,20 @@ func TestParse(t *testing.T) { { "reschedule-job.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), - Type: helper.StringToPtr("batch"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), + Type: stringToPtr("batch"), Datacenters: []string{"dc1"}, Reschedule: &api.ReschedulePolicy{ - Attempts: helper.IntToPtr(15), - Interval: helper.TimeToPtr(30 * time.Minute), - DelayFunction: helper.StringToPtr("constant"), - Delay: helper.TimeToPtr(10 * time.Second), + Attempts: intToPtr(15), + Interval: timeToPtr(30 * time.Minute), + DelayFunction: stringToPtr("constant"), + Delay: timeToPtr(10 * time.Second), }, TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("bar"), - Count: helper.IntToPtr(3), + Name: stringToPtr("bar"), + Count: intToPtr(3), Tasks: []*api.Task{ { Name: "bar", @@ -993,20 +1003,20 @@ func TestParse(t *testing.T) { { "reschedule-job-unlimited.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), - Type: helper.StringToPtr("batch"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), + Type: stringToPtr("batch"), Datacenters: []string{"dc1"}, Reschedule: &api.ReschedulePolicy{ - DelayFunction: helper.StringToPtr("exponential"), - Delay: helper.TimeToPtr(10 * time.Second), - MaxDelay: helper.TimeToPtr(120 * time.Second), - Unlimited: helper.BoolToPtr(true), + DelayFunction: stringToPtr("exponential"), + Delay: timeToPtr(10 * time.Second), + MaxDelay: timeToPtr(120 * time.Second), + Unlimited: boolToPtr(true), }, TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("bar"), - Count: helper.IntToPtr(3), + Name: stringToPtr("bar"), + Count: intToPtr(3), Tasks: []*api.Task{ { Name: "bar", @@ -1025,25 +1035,25 @@ func TestParse(t *testing.T) { { "migrate-job.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), - Type: helper.StringToPtr("batch"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), + Type: 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), + MaxParallel: intToPtr(2), + HealthCheck: stringToPtr("task_states"), + MinHealthyTime: timeToPtr(11 * time.Second), + HealthyDeadline: timeToPtr(11 * time.Minute), }, TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("bar"), - Count: helper.IntToPtr(3), + Name: stringToPtr("bar"), + Count: 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), + MaxParallel: intToPtr(3), + HealthCheck: stringToPtr("checks"), + MinHealthyTime: timeToPtr(1 * time.Second), + HealthyDeadline: timeToPtr(1 * time.Minute), }, Tasks: []*api.Task{ { @@ -1063,14 +1073,14 @@ func TestParse(t *testing.T) { { "tg-network.hcl", &api.Job{ - ID: helper.StringToPtr("foo"), - Name: helper.StringToPtr("foo"), + ID: stringToPtr("foo"), + Name: stringToPtr("foo"), Datacenters: []string{"dc1"}, TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("bar"), - ShutdownDelay: helper.TimeToPtr(14 * time.Second), - Count: helper.IntToPtr(3), + Name: stringToPtr("bar"), + ShutdownDelay: timeToPtr(14 * time.Second), + Count: intToPtr(3), Networks: []*api.NetworkResource{ { Mode: "bridge", @@ -1109,13 +1119,13 @@ func TestParse(t *testing.T) { }, SidecarTask: &api.SidecarTask{ Resources: &api.Resources{ - CPU: helper.IntToPtr(500), - MemoryMB: helper.IntToPtr(1024), + CPU: intToPtr(500), + MemoryMB: intToPtr(1024), }, Env: map[string]string{ "FOO": "abc", }, - ShutdownDelay: helper.TimeToPtr(5 * time.Second), + ShutdownDelay: timeToPtr(5 * time.Second), }, }, }, @@ -1131,7 +1141,7 @@ func TestParse(t *testing.T) { Resources: &api.Resources{ Networks: []*api.NetworkResource{ { - MBits: helper.IntToPtr(10), + MBits: intToPtr(10), }, }, }, @@ -1146,12 +1156,12 @@ func TestParse(t *testing.T) { { "tg-service-check.hcl", &api.Job{ - ID: helper.StringToPtr("group_service_check_script"), - Name: helper.StringToPtr("group_service_check_script"), + ID: stringToPtr("group_service_check_script"), + Name: stringToPtr("group_service_check_script"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), - Count: helper.IntToPtr(1), + Name: stringToPtr("group"), + Count: intToPtr(1), Networks: []*api.NetworkResource{ { Mode: "bridge", @@ -1190,10 +1200,10 @@ func TestParse(t *testing.T) { { "tg-service-proxy-expose.hcl", &api.Job{ - ID: helper.StringToPtr("group_service_proxy_expose"), - Name: helper.StringToPtr("group_service_proxy_expose"), + ID: stringToPtr("group_service_proxy_expose"), + Name: stringToPtr("group_service_proxy_expose"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", Connect: &api.ConsulConnect{ @@ -1223,11 +1233,11 @@ func TestParse(t *testing.T) { { "tg-service-connect-sidecar_task-name.hcl", &api.Job{ - ID: helper.StringToPtr("sidecar_task_name"), - Name: helper.StringToPtr("sidecar_task_name"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("sidecar_task_name"), + Name: stringToPtr("sidecar_task_name"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", Connect: &api.ConsulConnect{ @@ -1245,11 +1255,11 @@ func TestParse(t *testing.T) { { "tg-service-connect-proxy.hcl", &api.Job{ - ID: helper.StringToPtr("service-connect-proxy"), - Name: helper.StringToPtr("service-connect-proxy"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("service-connect-proxy"), + Name: stringToPtr("service-connect-proxy"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", Connect: &api.ConsulConnect{ @@ -1292,11 +1302,11 @@ func TestParse(t *testing.T) { { "tg-service-connect-local-service.hcl", &api.Job{ - ID: helper.StringToPtr("connect-proxy-local-service"), - Name: helper.StringToPtr("connect-proxy-local-service"), - Type: helper.StringToPtr("service"), + ID: stringToPtr("connect-proxy-local-service"), + Name: stringToPtr("connect-proxy-local-service"), + Type: stringToPtr("service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", Connect: &api.ConsulConnect{ @@ -1316,10 +1326,10 @@ func TestParse(t *testing.T) { { "tg-service-check-expose.hcl", &api.Job{ - ID: helper.StringToPtr("group_service_proxy_expose"), - Name: helper.StringToPtr("group_service_proxy_expose"), + ID: stringToPtr("group_service_proxy_expose"), + Name: stringToPtr("group_service_proxy_expose"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", Connect: &api.ConsulConnect{ @@ -1342,10 +1352,10 @@ func TestParse(t *testing.T) { { "tg-service-connect-native.hcl", &api.Job{ - ID: helper.StringToPtr("connect_native_service"), - Name: helper.StringToPtr("connect_native_service"), + ID: stringToPtr("connect_native_service"), + Name: stringToPtr("connect_native_service"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", TaskName: "task1", @@ -1360,10 +1370,10 @@ func TestParse(t *testing.T) { { "tg-service-enable-tag-override.hcl", &api.Job{ - ID: helper.StringToPtr("group_service_eto"), - Name: helper.StringToPtr("group_service_eto"), + ID: stringToPtr("group_service_eto"), + Name: stringToPtr("group_service_eto"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "example", EnableTagOverride: true, @@ -1376,21 +1386,21 @@ func TestParse(t *testing.T) { { "tg-scaling-policy.hcl", &api.Job{ - ID: helper.StringToPtr("elastic"), - Name: helper.StringToPtr("elastic"), + ID: stringToPtr("elastic"), + Name: stringToPtr("elastic"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Scaling: &api.ScalingPolicy{ - Min: helper.Int64ToPtr(5), - Max: helper.Int64ToPtr(100), + Min: int64ToPtr(5), + Max: int64ToPtr(100), Policy: map[string]interface{}{ "foo": "bar", "b": true, "val": 5, "f": .1, }, - Enabled: helper.BoolToPtr(false), + Enabled: boolToPtr(false), }, }, }, @@ -1400,16 +1410,16 @@ func TestParse(t *testing.T) { { "tg-service-connect-gateway-ingress.hcl", &api.Job{ - ID: helper.StringToPtr("connect_gateway_ingress"), - Name: helper.StringToPtr("connect_gateway_ingress"), + ID: stringToPtr("connect_gateway_ingress"), + Name: stringToPtr("connect_gateway_ingress"), TaskGroups: []*api.TaskGroup{{ - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Services: []*api.Service{{ Name: "ingress-gateway-service", Connect: &api.ConsulConnect{ Gateway: &api.ConsulGateway{ Proxy: &api.ConsulGatewayProxy{ - ConnectTimeout: helper.TimeToPtr(3 * time.Second), + ConnectTimeout: timeToPtr(3 * time.Second), EnvoyGatewayBindTaggedAddresses: true, EnvoyGatewayBindAddresses: map[string]*api.ConsulGatewayBindAddress{ "listener1": {Address: "10.0.0.1", Port: 8888}, @@ -1457,14 +1467,14 @@ func TestParse(t *testing.T) { { "tg-scaling-policy-minimal.hcl", &api.Job{ - ID: helper.StringToPtr("elastic"), - Name: helper.StringToPtr("elastic"), + ID: stringToPtr("elastic"), + Name: stringToPtr("elastic"), TaskGroups: []*api.TaskGroup{ { - Name: helper.StringToPtr("group"), + Name: stringToPtr("group"), Scaling: &api.ScalingPolicy{ Min: nil, - Max: helper.Int64ToPtr(10), + Max: int64ToPtr(10), Policy: nil, Enabled: nil, }, @@ -1489,23 +1499,23 @@ func TestParse(t *testing.T) { { "multiregion.hcl", &api.Job{ - ID: helper.StringToPtr("multiregion_job"), - Name: helper.StringToPtr("multiregion_job"), + ID: stringToPtr("multiregion_job"), + Name: stringToPtr("multiregion_job"), Multiregion: &api.Multiregion{ Strategy: &api.MultiregionStrategy{ - MaxParallel: helper.IntToPtr(1), - OnFailure: helper.StringToPtr("fail_all"), + MaxParallel: intToPtr(1), + OnFailure: stringToPtr("fail_all"), }, Regions: []*api.MultiregionRegion{ { Name: "west", - Count: helper.IntToPtr(2), + Count: intToPtr(2), Datacenters: []string{"west-1"}, Meta: map[string]string{"region_code": "W"}, }, { Name: "east", - Count: helper.IntToPtr(1), + Count: intToPtr(1), Datacenters: []string{"east-1", "east-2"}, Meta: map[string]string{"region_code": "E"}, },