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 }
// reservePortsForClient reserves a range of ports for the client to use when // it creates various plugins for log collection, executors, drivers, etc func (a *Agent) reservePortsForClient(conf *clientconfig.Config) error { // finding the device name for loopback deviceName, addr, mask, err := a.findLoopbackDevice() if err != nil { return fmt.Errorf("error finding the device name for loopback: %v", err) } // seeing if the user has already reserved some resources on this device var nr *structs.NetworkResource if conf.Node.Reserved == nil { conf.Node.Reserved = &structs.Resources{} } for _, n := range conf.Node.Reserved.Networks { if n.Device == deviceName { nr = n } } // If the user hasn't already created the device, we create it if nr == nil { nr = &structs.NetworkResource{ Device: deviceName, IP: addr, CIDR: mask, ReservedPorts: make([]structs.Port, 0), } } // appending the port ranges we want to use for the client to the list of // reserved ports for this device for i := conf.ClientMinPort; i <= conf.ClientMaxPort; i++ { nr.ReservedPorts = append(nr.ReservedPorts, structs.Port{Label: fmt.Sprintf("plugin-%d", i), Value: int(i)}) } conf.Node.Reserved.Networks = append(conf.Node.Reserved.Networks, nr) return nil }
// setupClient is used to setup the client if enabled func (a *Agent) setupClient() error { if !a.config.Client.Enabled { return nil } // Setup the configuration conf := a.config.ClientConfig if conf == nil { conf = client.DefaultConfig() } if a.server != nil { conf.RPCHandler = a.server } conf.LogOutput = a.logOutput conf.DevMode = a.config.DevMode if a.config.Region != "" { conf.Region = a.config.Region } if a.config.DataDir != "" { conf.StateDir = filepath.Join(a.config.DataDir, "client") conf.AllocDir = filepath.Join(a.config.DataDir, "alloc") } if a.config.Client.StateDir != "" { conf.StateDir = a.config.Client.StateDir } if a.config.Client.AllocDir != "" { conf.AllocDir = a.config.Client.AllocDir } conf.Servers = a.config.Client.Servers if a.config.Client.NetworkInterface != "" { conf.NetworkInterface = a.config.Client.NetworkInterface } conf.Options = a.config.Client.Options if a.config.Client.NetworkSpeed != 0 { conf.NetworkSpeed = a.config.Client.NetworkSpeed } if a.config.Client.MaxKillTimeout != "" { dur, err := time.ParseDuration(a.config.Client.MaxKillTimeout) if err != nil { return fmt.Errorf("Error parsing retry interval: %s", err) } conf.MaxKillTimeout = dur } conf.ClientMaxPort = a.config.Client.ClientMaxPort conf.ClientMinPort = a.config.Client.ClientMinPort // Setup the node conf.Node = new(structs.Node) conf.Node.Datacenter = a.config.Datacenter conf.Node.Name = a.config.NodeName conf.Node.Meta = a.config.Client.Meta conf.Node.NodeClass = a.config.Client.NodeClass httpAddr := fmt.Sprintf("%s:%d", a.config.BindAddr, a.config.Ports.HTTP) if a.config.Addresses.HTTP != "" && a.config.AdvertiseAddrs.HTTP == "" { addr, err := net.ResolveTCPAddr("tcp", a.config.Addresses.HTTP) if err != nil { return fmt.Errorf("error resolving http addr: %v:", err) } httpAddr = fmt.Sprintf("%s:%d", addr.IP.String(), addr.Port) } else if a.config.AdvertiseAddrs.HTTP != "" { addr, err := net.ResolveTCPAddr("tcp", a.config.AdvertiseAddrs.HTTP) if err != nil { return fmt.Errorf("error resolving advertise http addr: %v", err) } httpAddr = fmt.Sprintf("%s:%d", addr.IP.String(), addr.Port) } conf.Node.HTTPAddr = httpAddr // Reserve some ports for the plugins if runtime.GOOS == "windows" { deviceName, err := a.findLoopbackDevice() if err != nil { return fmt.Errorf("error finding the device name for loopback: %v", err) } var nr *structs.NetworkResource for _, n := range conf.Node.Reserved.Networks { if n.Device == deviceName { nr = n } } if nr == nil { nr = &structs.NetworkResource{ Device: deviceName, ReservedPorts: make([]structs.Port, 0), } } for i := conf.ClientMinPort; i <= conf.ClientMaxPort; i++ { nr.ReservedPorts = append(nr.ReservedPorts, structs.Port{Label: fmt.Sprintf("plugin-%d", i), Value: int(i)}) } } // Create the client client, err := client.NewClient(conf) if err != nil { return fmt.Errorf("client setup failed: %v", err) } a.client = client return nil }