github.com/adityamillind98/nomad@v0.11.8/jobspec/parse_network.go (about) 1 package jobspec 2 3 import ( 4 "fmt" 5 "strings" 6 7 multierror "github.com/hashicorp/go-multierror" 8 "github.com/hashicorp/hcl" 9 "github.com/hashicorp/hcl/hcl/ast" 10 "github.com/hashicorp/nomad/api" 11 "github.com/hashicorp/nomad/helper" 12 "github.com/mitchellh/mapstructure" 13 ) 14 15 // ParseNetwork parses a collection containing exactly one NetworkResource 16 func ParseNetwork(o *ast.ObjectList) (*api.NetworkResource, error) { 17 if len(o.Items) > 1 { 18 return nil, fmt.Errorf("only one 'network' resource allowed") 19 } 20 21 // Check for invalid keys 22 valid := []string{ 23 "mode", 24 "mbits", 25 "port", 26 } 27 if err := helper.CheckHCLKeys(o.Items[0].Val, valid); err != nil { 28 return nil, multierror.Prefix(err, "network ->") 29 } 30 31 var r api.NetworkResource 32 var m map[string]interface{} 33 if err := hcl.DecodeObject(&m, o.Items[0].Val); err != nil { 34 return nil, err 35 } 36 if err := mapstructure.WeakDecode(m, &r); err != nil { 37 return nil, err 38 } 39 40 var networkObj *ast.ObjectList 41 if ot, ok := o.Items[0].Val.(*ast.ObjectType); ok { 42 networkObj = ot.List 43 } else { 44 return nil, fmt.Errorf("should be an object") 45 } 46 if err := parsePorts(networkObj, &r); err != nil { 47 return nil, multierror.Prefix(err, "network, ports ->") 48 } 49 50 return &r, nil 51 } 52 53 func parsePorts(networkObj *ast.ObjectList, nw *api.NetworkResource) error { 54 // Check for invalid keys 55 valid := []string{ 56 "mbits", 57 "port", 58 "mode", 59 } 60 if err := helper.CheckHCLKeys(networkObj, valid); err != nil { 61 return err 62 } 63 64 portsObjList := networkObj.Filter("port") 65 knownPortLabels := make(map[string]bool) 66 for _, port := range portsObjList.Items { 67 if len(port.Keys) == 0 { 68 return fmt.Errorf("ports must be named") 69 } 70 label := port.Keys[0].Token.Value().(string) 71 if !reDynamicPorts.MatchString(label) { 72 return errPortLabel 73 } 74 l := strings.ToLower(label) 75 if knownPortLabels[l] { 76 return fmt.Errorf("found a port label collision: %s", label) 77 } 78 var p map[string]interface{} 79 var res api.Port 80 if err := hcl.DecodeObject(&p, port.Val); err != nil { 81 return err 82 } 83 if err := mapstructure.WeakDecode(p, &res); err != nil { 84 return err 85 } 86 res.Label = label 87 if res.Value > 0 { 88 nw.ReservedPorts = append(nw.ReservedPorts, res) 89 } else { 90 nw.DynamicPorts = append(nw.DynamicPorts, res) 91 } 92 knownPortLabels[l] = true 93 } 94 return nil 95 }