func parseJob(result *structs.Job, obj *hclobj.Object) error { if obj.Len() > 1 { return fmt.Errorf("only one 'job' block allowed") } // Get our job object obj = obj.Elem(true)[0] // Decode the full thing into a map[string]interface for ease var m map[string]interface{} if err := hcl.DecodeObject(&m, obj); err != nil { return err } delete(m, "constraint") delete(m, "meta") delete(m, "update") // Set the ID and name to the object key result.ID = obj.Key result.Name = obj.Key // Defaults result.Priority = 50 result.Region = "global" result.Type = "service" // Decode the rest if err := mapstructure.WeakDecode(m, result); err != nil { return err } // Parse constraints if o := obj.Get("constraint", false); o != nil { if err := parseConstraints(&result.Constraints, o); err != nil { return err } } // If we have an update strategy, then parse that if o := obj.Get("update", false); o != nil { if err := parseUpdate(&result.Update, o); err != nil { return err } } // Parse out meta fields. These are in HCL as a list so we need // to iterate over them and merge them. if metaO := obj.Get("meta", false); metaO != nil { for _, o := range metaO.Elem(false) { var m map[string]interface{} if err := hcl.DecodeObject(&m, o); err != nil { return err } if err := mapstructure.WeakDecode(m, &result.Meta); err != nil { return err } } } // If we have tasks outside, do those if o := obj.Get("task", false); o != nil { var tasks []*structs.Task if err := parseTasks(&tasks, o); err != nil { return err } result.TaskGroups = make([]*structs.TaskGroup, len(tasks), len(tasks)*2) for i, t := range tasks { result.TaskGroups[i] = &structs.TaskGroup{ Name: t.Name, Count: 1, Tasks: []*structs.Task{t}, } } } // Parse the task groups if o := obj.Get("group", false); o != nil { if err := parseGroups(result, o); err != nil { return fmt.Errorf("error parsing 'group': %s", err) } } return nil }
func parseJob(result *structs.Job, list *ast.ObjectList) error { list = list.Children() if len(list.Items) != 1 { return fmt.Errorf("only one 'job' block allowed") } // Get our job object obj := list.Items[0] // Decode the full thing into a map[string]interface for ease var m map[string]interface{} if err := hcl.DecodeObject(&m, obj.Val); err != nil { return err } delete(m, "constraint") delete(m, "meta") delete(m, "update") delete(m, "periodic") // Set the ID and name to the object key result.ID = obj.Keys[0].Token.Value().(string) result.Name = result.ID // Defaults result.Priority = 50 result.Region = "global" result.Type = "service" // Decode the rest if err := mapstructure.WeakDecode(m, result); err != nil { return err } // Value should be an object var listVal *ast.ObjectList if ot, ok := obj.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return fmt.Errorf("job '%s' value: should be an object", result.ID) } // Check for invalid keys valid := []string{ "id", "name", "region", "all_at_once", "type", "priority", "datacenters", "constraint", "update", "periodic", "meta", "task", "group", "vault_token", } if err := checkHCLKeys(listVal, valid); err != nil { return multierror.Prefix(err, "job:") } // Parse constraints if o := listVal.Filter("constraint"); len(o.Items) > 0 { if err := parseConstraints(&result.Constraints, o); err != nil { return multierror.Prefix(err, "constraint ->") } } // If we have an update strategy, then parse that if o := listVal.Filter("update"); len(o.Items) > 0 { if err := parseUpdate(&result.Update, o); err != nil { return multierror.Prefix(err, "update ->") } } // If we have a periodic definition, then parse that if o := listVal.Filter("periodic"); len(o.Items) > 0 { if err := parsePeriodic(&result.Periodic, o); err != nil { return multierror.Prefix(err, "periodic ->") } } // Parse out meta fields. These are in HCL as a list so we need // to iterate over them and merge them. if metaO := listVal.Filter("meta"); len(metaO.Items) > 0 { for _, o := range metaO.Elem().Items { var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } if err := mapstructure.WeakDecode(m, &result.Meta); err != nil { return err } } } // If we have tasks outside, create TaskGroups for them if o := listVal.Filter("task"); len(o.Items) > 0 { var tasks []*structs.Task if err := parseTasks(result.Name, "", &tasks, o); err != nil { return multierror.Prefix(err, "task:") } result.TaskGroups = make([]*structs.TaskGroup, len(tasks), len(tasks)*2) for i, t := range tasks { result.TaskGroups[i] = &structs.TaskGroup{ Name: t.Name, Count: 1, LocalDisk: structs.DefaultLocalDisk(), Tasks: []*structs.Task{t}, } } } // Parse the task groups if o := listVal.Filter("group"); len(o.Items) > 0 { if err := parseGroups(result, o); err != nil { return multierror.Prefix(err, "group:") } } return nil }
func parseJob(result *structs.Job, list *ast.ObjectList) error { list = list.Children() if len(list.Items) != 1 { return fmt.Errorf("only one 'job' block allowed") } // Get our job object obj := list.Items[0] // Decode the full thing into a map[string]interface for ease var m map[string]interface{} if err := hcl.DecodeObject(&m, obj.Val); err != nil { return err } delete(m, "constraint") delete(m, "meta") delete(m, "update") // Set the ID and name to the object key result.ID = obj.Keys[0].Token.Value().(string) result.Name = result.ID // Defaults result.Priority = 50 result.Region = "global" result.Type = "service" // Decode the rest if err := mapstructure.WeakDecode(m, result); err != nil { return err } // Value should be an object var listVal *ast.ObjectList if ot, ok := obj.Val.(*ast.ObjectType); ok { listVal = ot.List } else { return fmt.Errorf("job '%s' value: should be an object", result.ID) } // Parse constraints if o := listVal.Filter("constraint"); len(o.Items) > 0 { if err := parseConstraints(&result.Constraints, o); err != nil { return err } } // If we have an update strategy, then parse that if o := listVal.Filter("update"); len(o.Items) > 0 { if err := parseUpdate(&result.Update, o); err != nil { return err } } // Parse out meta fields. These are in HCL as a list so we need // to iterate over them and merge them. if metaO := listVal.Filter("meta"); len(metaO.Items) > 0 { for _, o := range metaO.Elem().Items { var m map[string]interface{} if err := hcl.DecodeObject(&m, o.Val); err != nil { return err } if err := mapstructure.WeakDecode(m, &result.Meta); err != nil { return err } } } // If we have tasks outside, create TaskGroups for them if o := listVal.Filter("task"); len(o.Items) > 0 { var tasks []*structs.Task if err := parseTasks(result.Name, "", &tasks, o); err != nil { return err } result.TaskGroups = make([]*structs.TaskGroup, len(tasks), len(tasks)*2) for i, t := range tasks { result.TaskGroups[i] = &structs.TaskGroup{ Name: t.Name, Count: 1, Tasks: []*structs.Task{t}, RestartPolicy: structs.NewRestartPolicy(result.Type), } } } // Parse the task groups if o := listVal.Filter("group"); len(o.Items) > 0 { if err := parseGroups(result, o); err != nil { return fmt.Errorf("error parsing 'group': %s", err) } } return nil }