// parse a FleetOptions func (options *FleetOptions) parse(obj *ast.ObjectType, c Cluster) error { // Parse the object excludeList := []string{ "after", "wants", "requires", "global-instance-constraints", } if err := hclutil.Decode(obj, excludeList, nil, options); err != nil { return maskAny(err) } // Parse after if o := obj.List.Filter("after"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("after of cluster '%s'", c.Stack)) if err != nil { return maskAny(err) } options.After = list } // Parse wants if o := obj.List.Filter("wants"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("wants of cluster '%s'", c.Stack)) if err != nil { return maskAny(err) } options.Wants = list } // Parse requires if o := obj.List.Filter("requires"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("requires of cluster '%s'", c.Stack)) if err != nil { return maskAny(err) } options.Requires = list } // Parse global-instance-constraints if o := obj.List.Filter("global-instance-constraints"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("global-instance-constraints of cluster '%s'", c.Stack)) if err != nil { return maskAny(err) } options.GlobalInstanceConstraints = list } return nil }
// parse a DockerOptions func (options *DockerOptions) parse(obj *ast.ObjectType, c Cluster) error { // Parse the object excludeList := []string{ "log-args", } if err := hclutil.Decode(obj, excludeList, nil, options); err != nil { return maskAny(err) } // Parse log-args if o := obj.List.Filter("log-args"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("log-args of cluster '%s'", c.Stack)) if err != nil { return maskAny(err) } options.LoggingArgs = append(options.LoggingArgs, list...) } return nil }
// parse a task func (t *parseTask) parse(obj *ast.ObjectType, anonymousGroup bool) error { // Build the task excludedKeys := []string{ "env", "image", "after", "volumes", "volumes-from", "frontend", "private-frontend", "capabilities", "links", "link", "secret", "constraint", "rewrite", "metrics", } defaultValues := map[string]interface{}{ "count": defaultCount, } if err := hclutil.Decode(obj, excludedKeys, defaultValues, t); err != nil { return maskAny(err) } if !anonymousGroup { if t.Count != defaultCount { return maskAny(errgo.WithCausef(nil, ValidationError, "count is not allowed in of task %s", t.Name)) } if t.Global { return maskAny(errgo.WithCausef(nil, ValidationError, "global is not allowed in of task %s", t.Name)) } } if o := obj.List.Filter("image"); len(o.Items) > 0 { if len(o.Items) > 1 { return maskAny(errgo.WithCausef(nil, ValidationError, "task %s defines multiple images", t.Name)) } if obj, ok := o.Items[0].Val.(*ast.LiteralType); ok && obj.Token.Type == token.STRING { img, err := ParseDockerImage(obj.Token.Value().(string)) if err != nil { return maskAny(err) } t.Image = img } else { return maskAny(errgo.WithCausef(nil, ValidationError, "image for task %s is not a string", t.Name)) } } else if t.Type != "proxy" { return maskAny(errgo.WithCausef(nil, ValidationError, "image missing for task %s", t.Name)) } // If we have env, then parse them if o := obj.List.Filter("env"); len(o.Items) > 0 { for _, o := range o.Elem().Items { if err := hclutil.Decode(o.Val, nil, nil, &t.Environment); err != nil { return maskAny(err) } } } // Parse after if o := obj.List.Filter("after"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("after of task %s", t.Name)) if err != nil { return maskAny(err) } for _, x := range list { t.After = append(t.After, TaskName(x)) } } // Parse volumes if o := obj.List.Filter("volumes"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("volumes of task %s", t.Name)) if err != nil { return maskAny(err) } for _, x := range list { vol, err := ParseVolume(x) if err != nil { return maskAny(err) } t.Volumes = append(t.Volumes, vol) } } // Parse volumes-from if o := obj.List.Filter("volumes-from"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("volumes-from of task %s", t.Name)) if err != nil { return maskAny(err) } for _, x := range list { t.VolumesFrom = append(t.VolumesFrom, TaskName(x)) } } // Parse capabilities if o := obj.List.Filter("capabilities"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("capabilities of task %s", t.Name)) if err != nil { return maskAny(err) } t.Capabilities = list } // Parse link's if o := obj.List.Filter("link"); len(o.Items) > 0 { for _, o := range o.Children().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { l := Link{} if err := l.parse(obj); err != nil { return maskAny(err) } l.Target = LinkName(o.Keys[0].Token.Value().(string)).normalize() t.Links = append(t.Links, l) } else { return maskAny(errgo.WithCausef(nil, ValidationError, "link of task %s is not an object", t.Name)) } } } // Parse links if o := obj.List.Filter("links"); len(o.Items) > 0 { list, err := hclutil.ParseStringList(o, fmt.Sprintf("links of task %s", t.Name)) if err != nil { return maskAny(err) } for _, x := range list { t.Links = append(t.Links, Link{ Target: LinkName(x).normalize(), }) } } // Parse public frontends if o := obj.List.Filter("frontend"); len(o.Items) > 0 { for _, o := range o.Elem().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { f := PublicFrontEnd{} if err := f.parse(obj); err != nil { return maskAny(err) } t.PublicFrontEnds = append(t.PublicFrontEnds, f) } else { return maskAny(errgo.WithCausef(nil, ValidationError, "frontend of task %s is not an object or array", t.Name)) } } } // Parse private frontends if o := obj.List.Filter("private-frontend"); len(o.Items) > 0 { for _, o := range o.Elem().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { f := PrivateFrontEnd{} if err := f.parse(obj); err != nil { return maskAny(err) } t.PrivateFrontEnds = append(t.PrivateFrontEnds, f) } else { return maskAny(errgo.WithCausef(nil, ValidationError, "private-frontend of task %s is not an object or array", t.Name)) } } } // Parse secrets if o := obj.List.Filter("secret"); len(o.Items) > 0 { for _, o := range o.Children().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { s := Secret{} n := o.Keys[0].Token.Value().(string) if err := s.parse(obj); err != nil { return maskAny(err) } s.Path = n t.Secrets = append(t.Secrets, s) } else { return maskAny(errgo.WithCausef(nil, ValidationError, "secret of task %s is not an object or array", t.Name)) } } } // Parse constraints if o := obj.List.Filter("constraint"); len(o.Items) > 0 { for _, o := range o.Elem().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { c := Constraint{} if err := c.parse(obj); err != nil { return maskAny(err) } t.Constraints = append(t.Constraints, c) } else { return maskAny(errgo.WithCausef(nil, ValidationError, "constraint of task %s is not an object", t.Name)) } } } // Parse rewrites if o := obj.List.Filter("rewrite"); len(o.Items) > 0 { for _, o := range o.Elem().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { r := Rewrite{} if err := r.parse(obj); err != nil { return maskAny(err) } if t.Rewrite != nil { r = t.Rewrite.Merge(r) } t.Rewrite = &r } else { return maskAny(errgo.WithCausef(nil, ValidationError, "rewrite of task %s is not an object", t.Name)) } } } // Parse metrics if o := obj.List.Filter("metrics"); len(o.Items) > 0 { if len(o.Items) > 1 { return maskAny(errgo.WithCausef(nil, ValidationError, "cannot more than 1 metrics object in %s", t.Name)) } for _, o := range o.Elem().Items { if obj, ok := o.Val.(*ast.ObjectType); ok { m := Metrics{} if err := m.parse(obj); err != nil { return maskAny(err) } t.Metrics = &m } else { return maskAny(errgo.WithCausef(nil, ValidationError, "metrics of task %s is not an object", t.Name)) } } } return nil }