func parseImport(result *File, list *ast.ObjectList) error { list = list.Children() if len(list.Items) == 0 { return nil } // Go through each object and turn it into an actual result. collection := make([]*Import, 0, len(list.Items)) seen := make(map[string]struct{}) for _, item := range list.Items { key := item.Keys[0].Token.Value().(string) // Make sure we haven't already found this import if _, ok := seen[key]; ok { return fmt.Errorf("import '%s' defined more than once", key) } seen[key] = struct{}{} // Check for invalid keys if err := checkHCLKeys(item.Val, nil); err != nil { return multierror.Prefix(err, fmt.Sprintf( "import '%s':", key)) } collection = append(collection, &Import{ Source: key, }) } result.Imports = collection return nil }
func parseFoundations(result *Infrastructure, list *ast.ObjectList) error { list = list.Children() if len(list.Items) == 0 { return nil } // Go through each object and turn it into an actual result. collection := make([]*Foundation, 0, len(list.Items)) seen := make(map[string]struct{}) for _, item := range list.Items { n := item.Keys[0].Token.Value().(string) // Make sure we haven't already found this if _, ok := seen[n]; ok { return fmt.Errorf("foundation '%s' defined more than once", n) } seen[n] = struct{}{} var m map[string]interface{} if err := hcl.DecodeObject(&m, item.Val); err != nil { return err } var f Foundation f.Name = n f.Config = m collection = append(collection, &f) } // Set the results result.Foundations = collection return nil }
func (j *Job) parseGroups(list *ast.ObjectList) error { list = list.Children() if len(list.Items) == 0 { return nil } seen := make(map[string]struct{}) for _, item := range list.Items { n := item.Keys[0].Token.Value().(string) // Make sure we haven't already found this if _, ok := seen[n]; ok { return fmt.Errorf("group '%s' defined more than once", n) } seen[n] = struct{}{} // We need this later obj, ok := item.Val.(*ast.ObjectType) if !ok { return fmt.Errorf("group '%s': should be an object", n) } // Build the group with the basic decode tg := &TaskGroup{} tg.Name = TaskGroupName(n) if err := tg.parse(obj); err != nil { return maskAny(err) } j.Groups = append(j.Groups, tg) } return nil }
// parse a list of tasks func (tasks *parseTaskList) parseTasks(list *ast.ObjectList, anonymousGroup bool) error { list = list.Children() if len(list.Items) == 0 { return nil } // Get all the maps of keys to the actual object seen := make(map[string]struct{}) for _, item := range list.Items { n := item.Keys[0].Token.Value().(string) if _, ok := seen[n]; ok { return fmt.Errorf("task '%s' defined more than once", n) } seen[n] = struct{}{} obj, ok := item.Val.(*ast.ObjectType) if !ok { return fmt.Errorf("task '%s': should be an object", n) } t := &parseTask{} t.Name = TaskName(n) if err := t.parse(obj, anonymousGroup); err != nil { return maskAny(err) } *tasks = append(*tasks, t) } return nil }
// LoadOutputsHcl recurses into the given HCL object and turns // it into a mapping of outputs. func loadOutputsHcl(list *ast.ObjectList) ([]*Output, error) { list = list.Children() if len(list.Items) == 0 { return nil, nil } // Go through each object and turn it into an actual result. result := make([]*Output, 0, len(list.Items)) for _, item := range list.Items { n := item.Keys[0].Token.Value().(string) var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } rawConfig, err := NewRawConfig(config) if err != nil { return nil, fmt.Errorf( "Error reading config for output %s: %s", n, err) } result = append(result, &Output{ Name: n, RawConfig: rawConfig, }) } return result, nil }
func parsePorts(networkObj *ast.ObjectList, nw *structs.NetworkResource) error { portsObjList := networkObj.Filter("port") knownPortLabels := make(map[string]bool) for _, port := range portsObjList.Items { if len(port.Keys) == 0 { return fmt.Errorf("ports must be named") } label := port.Keys[0].Token.Value().(string) if !reDynamicPorts.MatchString(label) { return errPortLabel } l := strings.ToLower(label) if knownPortLabels[l] { return fmt.Errorf("found a port label collision: %s", label) } var p map[string]interface{} var res structs.Port if err := hcl.DecodeObject(&p, port.Val); err != nil { return err } if err := mapstructure.WeakDecode(p, &res); err != nil { return err } res.Label = label if res.Value > 0 { nw.ReservedPorts = append(nw.ReservedPorts, res) } else { nw.DynamicPorts = append(nw.DynamicPorts, res) } knownPortLabels[l] = true } return nil }
func parseLocalDisk(result **structs.LocalDisk, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'local_disk' block allowed") } // Get our local_disk object obj := list.Items[0] // Check for invalid keys valid := []string{ "sticky", "disk", } if err := checkHCLKeys(obj.Val, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, obj.Val); err != nil { return err } var localDisk structs.LocalDisk if err := mapstructure.WeakDecode(m, &localDisk); err != nil { return err } *result = &localDisk return nil }
func parseRestartPolicy(final **structs.RestartPolicy, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'restart' block allowed") } // Get our job object obj := list.Items[0] var m map[string]interface{} if err := hcl.DecodeObject(&m, obj.Val); err != nil { return err } var result structs.RestartPolicy dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: &result, }) if err != nil { return err } if err := dec.Decode(m); err != nil { return err } *final = &result return nil }
func parseUpdate(result *structs.UpdateStrategy, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'update' block allowed per job") } // Get our resource object o := list.Items[0] var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } // Check for invalid keys valid := []string{ "stagger", "max_parallel", } if err := checkHCLKeys(o.Val, valid); err != nil { return err } dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: result, }) if err != nil { return err } return dec.Decode(m) }
func parseResources(result *structs.Resources, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) == 0 { return nil } if len(list.Items) > 1 { return fmt.Errorf("only one 'resource' block allowed per task") } // Get our resource object o := list.Items[0] // We need this later var listVal *ast.ObjectList if ot, ok := o.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return fmt.Errorf("resource: should be an object") } var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } delete(m, "network") if err := mapstructure.WeakDecode(m, result); err != nil { return err } // Parse the network resources if o := listVal.Filter("network"); len(o.Items) > 0 { if len(o.Items) > 1 { return fmt.Errorf("only one 'network' resource allowed") } var r structs.NetworkResource var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Items[0].Val); err != nil { return err } if err := mapstructure.WeakDecode(m, &r); err != nil { return err } var networkObj *ast.ObjectList if ot, ok := o.Items[0].Val.(*ast.ObjectType); ok { networkObj = ot.List } else { return fmt.Errorf("resource: should be an object") } if err := parsePorts(networkObj, &r); err != nil { return err } result.Networks = []*structs.NetworkResource{&r} } return nil }
func parseTLSConfig(result **config.TLSConfig, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'tls' block allowed") } // Get the TLS object listVal := list.Items[0].Val valid := []string{ "http", "rpc", "verify_server_hostname", "ca_file", "cert_file", "key_file", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var tlsConfig config.TLSConfig if err := mapstructure.WeakDecode(m, &tlsConfig); err != nil { return err } *result = &tlsConfig return nil }
func parseAdvertise(result **AdvertiseAddrs, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'advertise' block allowed") } // Get our advertise object listVal := list.Items[0].Val // Check for invalid keys valid := []string{ "http", "rpc", "serf", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var advertise AdvertiseAddrs if err := mapstructure.WeakDecode(m, &advertise); err != nil { return err } *result = &advertise return nil }
func parseTelemetry(result **Telemetry, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'telemetry' block allowed") } // Get our telemetry object listVal := list.Items[0].Val // Check for invalid keys valid := []string{ "statsite_address", "statsd_address", "disable_hostname", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var telemetry Telemetry if err := mapstructure.WeakDecode(m, &telemetry); err != nil { return err } *result = &telemetry return nil }
func loadConfigOutputs(hclConfig *ast.ObjectList) ([]*tfcfg.Output, error) { hclConfig = hclConfig.Children() result := make([]*tfcfg.Output, 0, len(hclConfig.Items)) if len(hclConfig.Items) == 0 { return result, nil } for _, item := range hclConfig.Items { n := item.Keys[0].Token.Value().(string) if _, ok := item.Val.(*ast.ObjectType); !ok { return nil, fmt.Errorf("output '%s': should be a block", n) } var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } rawConfig, err := tfcfg.NewRawConfig(config) if err != nil { return nil, fmt.Errorf( "error reading output config %s: %s", n, err, ) } result = append(result, &tfcfg.Output{ Name: n, RawConfig: rawConfig, }) } return result, nil }
func parseAtlas(result **AtlasConfig, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'atlas' block allowed") } // Get our atlas object listVal := list.Items[0].Val // Check for invalid keys valid := []string{ "infrastructure", "token", "join", "endpoint", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var atlas AtlasConfig if err := mapstructure.WeakDecode(m, &atlas); err != nil { return err } *result = &atlas return nil }
// LoadOutputsHcl recurses into the given HCL object and turns // it into a mapping of outputs. func loadOutputsHcl(list *ast.ObjectList) ([]*Output, error) { list = list.Children() if len(list.Items) == 0 { return nil, fmt.Errorf( "'output' must be followed by exactly one string: a name") } // Go through each object and turn it into an actual result. result := make([]*Output, 0, len(list.Items)) for _, item := range list.Items { n := item.Keys[0].Token.Value().(string) var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return nil, fmt.Errorf("output '%s': should be an object", n) } var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } // Delete special keys delete(config, "depends_on") rawConfig, err := NewRawConfig(config) if err != nil { return nil, fmt.Errorf( "Error reading config for output %s: %s", n, err) } // If we have depends fields, then add those in var dependsOn []string if o := listVal.Filter("depends_on"); len(o.Items) > 0 { err := hcl.DecodeObject(&dependsOn, o.Items[0].Val) if err != nil { return nil, fmt.Errorf( "Error reading depends_on for output %q: %s", n, err) } } result = append(result, &Output{ Name: n, RawConfig: rawConfig, DependsOn: dependsOn, }) } return result, nil }
func parseServices(jobName string, taskGroupName string, task *structs.Task, serviceObjs *ast.ObjectList) error { task.Services = make([]*structs.Service, len(serviceObjs.Items)) var defaultServiceName bool for idx, o := range serviceObjs.Items { // Check for invalid keys valid := []string{ "name", "tags", "port", "check", } if err := checkHCLKeys(o.Val, valid); err != nil { return multierror.Prefix(err, fmt.Sprintf("service (%d) ->", idx)) } var service structs.Service var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } delete(m, "check") if err := mapstructure.WeakDecode(m, &service); err != nil { return err } if defaultServiceName && service.Name == "" { return fmt.Errorf("Only one service block may omit the Name field") } if service.Name == "" { defaultServiceName = true service.Name = fmt.Sprintf("%s-%s-%s", jobName, taskGroupName, task.Name) } // Filter checks var checkList *ast.ObjectList if ot, ok := o.Val.(*ast.ObjectType); ok { checkList = ot.List } else { return fmt.Errorf("service '%s': should be an object", service.Name) } if co := checkList.Filter("check"); len(co.Items) > 0 { if err := parseChecks(&service, co); err != nil { return multierror.Prefix(err, fmt.Sprintf("service: '%s',", service.Name)) } } task.Services[idx] = &service } return nil }
func parseTelemetry(result **Telemetry, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'telemetry' block allowed") } // Get our telemetry object listVal := list.Items[0].Val // Check for invalid keys valid := []string{ "statsite_address", "statsd_address", "disable_hostname", "collection_interval", "publish_allocation_metrics", "publish_node_metrics", "datadog_address", "circonus_api_token", "circonus_api_app", "circonus_api_url", "circonus_submission_interval", "circonus_submission_url", "circonus_check_id", "circonus_check_force_metric_activation", "circonus_check_instance_id", "circonus_check_search_tag", "circonus_check_display_name", "circonus_check_tags", "circonus_broker_id", "circonus_broker_select_tag", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var telemetry Telemetry if err := mapstructure.WeakDecode(m, &telemetry); err != nil { return err } if telemetry.CollectionInterval != "" { if dur, err := time.ParseDuration(telemetry.CollectionInterval); err != nil { return fmt.Errorf("error parsing value of %q: %v", "collection_interval", err) } else { telemetry.collectionInterval = dur } } *result = &telemetry return nil }
// LoadProvidersHcl recurses into the given HCL object and turns // it into a mapping of provider configs. func loadProvidersHcl(list *ast.ObjectList) ([]*ProviderConfig, error) { list = list.Children() if len(list.Items) == 0 { return nil, nil } // Go through each object and turn it into an actual result. result := make([]*ProviderConfig, 0, len(list.Items)) for _, item := range list.Items { n := item.Keys[0].Token.Value().(string) var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return nil, fmt.Errorf("module '%s': should be an object", n) } var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } delete(config, "alias") rawConfig, err := NewRawConfig(config) if err != nil { return nil, fmt.Errorf( "Error reading config for provider config %s: %s", n, err) } // If we have an alias field, then add those in var alias string if a := listVal.Filter("alias"); len(a.Items) > 0 { err := hcl.DecodeObject(&alias, a.Items[0].Val) if err != nil { return nil, fmt.Errorf( "Error reading alias for provider[%s]: %s", n, err) } } result = append(result, &ProviderConfig{ Name: n, Alias: alias, RawConfig: rawConfig, }) } return result, nil }
func parseConsulConfig(result **config.ConsulConfig, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'consul' block allowed") } // Get our Consul object listVal := list.Items[0].Val // Check for invalid keys valid := []string{ "address", "auth", "auto_advertise", "ca_file", "cert_file", "checks_use_advertise", "client_auto_join", "client_service_name", "key_file", "server_auto_join", "server_service_name", "ssl", "timeout", "token", "verify_ssl", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } consulConfig := config.DefaultConsulConfig() dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: &consulConfig, }) if err != nil { return err } if err := dec.Decode(m); err != nil { return err } *result = consulConfig return nil }
func parseConstraints(result *[]*structs.Constraint, list *ast.ObjectList) error { for _, o := range list.Elem().Items { var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } m["LTarget"] = m["attribute"] m["RTarget"] = m["value"] m["Operand"] = m["operator"] // If "version" is provided, set the operand // to "version" and the value to the "RTarget" if constraint, ok := m[structs.ConstraintVersion]; ok { m["Operand"] = structs.ConstraintVersion m["RTarget"] = constraint } // If "regexp" is provided, set the operand // to "regexp" and the value to the "RTarget" if constraint, ok := m[structs.ConstraintRegex]; ok { m["Operand"] = structs.ConstraintRegex m["RTarget"] = constraint } if value, ok := m[structs.ConstraintDistinctHosts]; ok { enabled, err := parseBool(value) if err != nil { return fmt.Errorf("distinct_hosts should be set to true or false; %v", err) } // If it is not enabled, skip the constraint. if !enabled { continue } m["Operand"] = structs.ConstraintDistinctHosts } // Build the constraint var c structs.Constraint if err := mapstructure.WeakDecode(m, &c); err != nil { return err } if c.Operand == "" { c.Operand = "=" } *result = append(*result, &c) } return nil }
func loadConfigProviders(hclConfig *ast.ObjectList) ([]*tfcfg.ProviderConfig, error) { hclConfig = hclConfig.Children() result := make([]*tfcfg.ProviderConfig, 0, len(hclConfig.Items)) if len(hclConfig.Items) == 0 { return result, nil } for _, item := range hclConfig.Items { n := item.Keys[0].Token.Value().(string) var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return nil, fmt.Errorf("provider '%s': should be a block", n) } var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } delete(config, "alias") rawConfig, err := tfcfg.NewRawConfig(config) if err != nil { return nil, fmt.Errorf( "error reading provider config %s: %s", n, err, ) } // If we have an alias, add it in var alias string if a := listVal.Filter("alias"); len(a.Items) > 0 { err := hcl.DecodeObject(&alias, a.Items[0].Val) if err != nil { return nil, fmt.Errorf( "error reading provider %s alias: %s", n, err, ) } } result = append(result, &tfcfg.ProviderConfig{ Name: n, Alias: alias, RawConfig: rawConfig, }) } return result, nil }
func loadConfigVariables(hclConfig *ast.ObjectList) ([]*tfcfg.Variable, error) { hclConfig = hclConfig.Children() result := make([]*tfcfg.Variable, 0, len(hclConfig.Items)) if len(hclConfig.Items) == 0 { return result, nil } for _, item := range hclConfig.Items { n := item.Keys[0].Token.Value().(string) var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return nil, fmt.Errorf("variable '%s': should be a block", n) } var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } variable := &tfcfg.Variable{ Name: n, } if a := listVal.Filter("default"); len(a.Items) > 0 { err := hcl.DecodeObject(&variable.Default, a.Items[0].Val) if err != nil { return nil, fmt.Errorf( "error reading variable %s default: %s", n, err, ) } } if a := listVal.Filter("description"); len(a.Items) > 0 { err := hcl.DecodeObject(&variable.Description, a.Items[0].Val) if err != nil { return nil, fmt.Errorf( "error reading variable %s description: %s", n, err, ) } } if a := listVal.Filter("type"); len(a.Items) > 0 { err := hcl.DecodeObject(&variable.DeclaredType, a.Items[0].Val) if err != nil { return nil, fmt.Errorf( "error reading variable %s type: %s", n, err, ) } } result = append(result, variable) } return result, nil }
func parseServer(result **ServerConfig, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'server' block allowed") } // Get our server object obj := list.Items[0] // Value should be an object var listVal *ast.ObjectList if ot, ok := obj.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return fmt.Errorf("client value: should be an object") } // Check for invalid keys valid := []string{ "enabled", "bootstrap_expect", "data_dir", "protocol_version", "num_schedulers", "enabled_schedulers", "node_gc_threshold", "heartbeat_grace", "start_join", "retry_join", "retry_max", "retry_interval", "rejoin_after_leave", "encrypt", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var config ServerConfig if err := mapstructure.WeakDecode(m, &config); err != nil { return err } *result = &config return nil }
func loadConfigModules(hclConfig *ast.ObjectList) ([]*tfcfg.Module, error) { hclConfig = hclConfig.Children() result := make([]*tfcfg.Module, 0, len(hclConfig.Items)) if len(hclConfig.Items) == 0 { return result, nil } for _, item := range hclConfig.Items { n := item.Keys[0].Token.Value().(string) var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return nil, fmt.Errorf("module '%s': should be a block", n) } var config map[string]interface{} if err := hcl.DecodeObject(&config, item.Val); err != nil { return nil, err } delete(config, "source") rawConfig, err := tfcfg.NewRawConfig(config) if err != nil { return nil, fmt.Errorf( "error reading module config %s: %s", n, err, ) } var source string if a := listVal.Filter("source"); len(a.Items) > 0 { err := hcl.DecodeObject(&source, a.Items[0].Val) if err != nil { return nil, fmt.Errorf( "error reading module %s source: %s", n, err, ) } } result = append(result, &tfcfg.Module{ Name: n, Source: source, RawConfig: rawConfig, }) } return result, nil }
func parseVaultConfig(result **config.VaultConfig, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'vault' block allowed") } // Get our Vault object listVal := list.Items[0].Val // Check for invalid keys valid := []string{ "address", "allow_unauthenticated", "enabled", "task_token_ttl", "ca_file", "ca_path", "cert_file", "key_file", "tls_server_name", "tls_skip_verify", "token", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } vaultConfig := config.DefaultVaultConfig() dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, Result: &vaultConfig, }) if err != nil { return err } if err := dec.Decode(m); err != nil { return err } *result = vaultConfig return nil }
func parseArtifacts(result *[]*structs.TaskArtifact, list *ast.ObjectList) error { for _, o := range list.Elem().Items { // Check for invalid keys valid := []string{ "source", "options", "destination", } if err := checkHCLKeys(o.Val, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } delete(m, "options") // Default to downloading to the local directory. if _, ok := m["destination"]; !ok { m["destination"] = "local/" } var ta structs.TaskArtifact if err := mapstructure.WeakDecode(m, &ta); err != nil { return err } var optionList *ast.ObjectList if ot, ok := o.Val.(*ast.ObjectType); ok { optionList = ot.List } else { return fmt.Errorf("artifact should be an object") } if oo := optionList.Filter("options"); len(oo.Items) > 0 { options := make(map[string]string) if err := parseArtifactOption(options, oo); err != nil { return multierror.Prefix(err, "options: ") } ta.GetterOptions = options } *result = append(*result, &ta) } return nil }
func parsePeriodic(result **structs.PeriodicConfig, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'periodic' block allowed per job") } // Get our resource object o := list.Items[0] var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } // Check for invalid keys valid := []string{ "enabled", "cron", "prohibit_overlap", } if err := checkHCLKeys(o.Val, valid); err != nil { return err } // Enabled by default if the periodic block exists. if value, ok := m["enabled"]; !ok { m["Enabled"] = true } else { enabled, err := parseBool(value) if err != nil { return fmt.Errorf("periodic.enabled should be set to true or false; %v", err) } m["Enabled"] = enabled } // If "cron" is provided, set the type to "cron" and store the spec. if cron, ok := m["cron"]; ok { m["SpecType"] = structs.PeriodicSpecCron m["Spec"] = cron } // Build the constraint var p structs.PeriodicConfig if err := mapstructure.WeakDecode(m, &p); err != nil { return err } *result = &p return nil }
func parseReserved(result **Resources, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) > 1 { return fmt.Errorf("only one 'reserved' block allowed") } // Get our reserved object obj := list.Items[0] // Value should be an object var listVal *ast.ObjectList if ot, ok := obj.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return fmt.Errorf("client value: should be an object") } // Check for invalid keys valid := []string{ "cpu", "memory", "disk", "iops", "reserved_ports", } if err := checkHCLKeys(listVal, valid); err != nil { return err } var m map[string]interface{} if err := hcl.DecodeObject(&m, listVal); err != nil { return err } var reserved Resources if err := mapstructure.WeakDecode(m, &reserved); err != nil { return err } if err := reserved.ParseReserved(); err != nil { return err } *result = &reserved return nil }
func parseVault(result *structs.Vault, list *ast.ObjectList) error { list = list.Elem() if len(list.Items) == 0 { return nil } if len(list.Items) > 1 { return fmt.Errorf("only one 'vault' block allowed per task") } // Get our resource object o := list.Items[0] // We need this later var listVal *ast.ObjectList if ot, ok := o.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return fmt.Errorf("vault: should be an object") } // Check for invalid keys valid := []string{ "policies", "env", } if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, "vault ->") } var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } // Default the env bool if _, ok := m["env"]; !ok { m["env"] = true } if err := mapstructure.WeakDecode(m, result); err != nil { return err } return nil }