// Set a new port value func (p *PortOpt) Set(value string) error { csvReader := csv.NewReader(strings.NewReader(value)) fields, err := csvReader.Read() if err != nil { return err } pConfig := swarm.PortConfig{} for _, field := range fields { parts := strings.SplitN(field, "=", 2) if len(parts) != 2 { return fmt.Errorf("invalid field %s", field) } key := strings.ToLower(parts[0]) value := strings.ToLower(parts[1]) switch key { case portOptProtocol: if value != string(swarm.PortConfigProtocolTCP) && value != string(swarm.PortConfigProtocolUDP) { return fmt.Errorf("invalid protocol value %s", value) } pConfig.Protocol = swarm.PortConfigProtocol(value) case portOptMode: if value != string(swarm.PortConfigPublishModeIngress) && value != string(swarm.PortConfigPublishModeHost) { return fmt.Errorf("invalid publish mode value %s", value) } pConfig.PublishMode = swarm.PortConfigPublishMode(value) case portOptTargetPort: tPort, err := strconv.ParseUint(value, 10, 16) if err != nil { return err } pConfig.TargetPort = uint32(tPort) case portOptPublishedPort: pPort, err := strconv.ParseUint(value, 10, 16) if err != nil { return err } pConfig.PublishedPort = uint32(pPort) default: return fmt.Errorf("invalid field key %s", key) } } if pConfig.TargetPort == 0 { return fmt.Errorf("missing mandatory field %q", portOptTargetPort) } p.ports = append(p.ports, pConfig) return nil }
// Set a new port value func (p *PortOpt) Set(value string) error { longSyntax, err := regexp.MatchString(`\w+=\w+(,\w+=\w+)*`, value) if err != nil { return err } if longSyntax { csvReader := csv.NewReader(strings.NewReader(value)) fields, err := csvReader.Read() if err != nil { return err } pConfig := swarm.PortConfig{} for _, field := range fields { parts := strings.SplitN(field, "=", 2) if len(parts) != 2 { return fmt.Errorf("invalid field %s", field) } key := strings.ToLower(parts[0]) value := strings.ToLower(parts[1]) switch key { case portOptProtocol: if value != string(swarm.PortConfigProtocolTCP) && value != string(swarm.PortConfigProtocolUDP) { return fmt.Errorf("invalid protocol value %s", value) } pConfig.Protocol = swarm.PortConfigProtocol(value) case portOptMode: if value != string(swarm.PortConfigPublishModeIngress) && value != string(swarm.PortConfigPublishModeHost) { return fmt.Errorf("invalid publish mode value %s", value) } pConfig.PublishMode = swarm.PortConfigPublishMode(value) case portOptTargetPort: tPort, err := strconv.ParseUint(value, 10, 16) if err != nil { return err } pConfig.TargetPort = uint32(tPort) case portOptPublishedPort: pPort, err := strconv.ParseUint(value, 10, 16) if err != nil { return err } pConfig.PublishedPort = uint32(pPort) default: return fmt.Errorf("invalid field key %s", key) } } if pConfig.TargetPort == 0 { return fmt.Errorf("missing mandatory field %q", portOptTargetPort) } if pConfig.PublishMode == "" { pConfig.PublishMode = swarm.PortConfigPublishModeIngress } if pConfig.Protocol == "" { pConfig.Protocol = swarm.PortConfigProtocolTCP } p.ports = append(p.ports, pConfig) } else { // short syntax portConfigs := []swarm.PortConfig{} // We can ignore errors because the format was already validated by ValidatePort ports, portBindings, _ := nat.ParsePortSpecs([]string{value}) for port := range ports { portConfigs = append(portConfigs, ConvertPortToPortConfig(port, portBindings)...) } p.ports = append(p.ports, portConfigs...) } return nil }