port.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package opts
  2. import (
  3. "encoding/csv"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "github.com/docker/docker/api/types/swarm"
  8. )
  9. const (
  10. portOptTargetPort = "target"
  11. portOptPublishedPort = "published"
  12. portOptProtocol = "protocol"
  13. portOptMode = "mode"
  14. )
  15. // PortOpt represents a port config in swarm mode.
  16. type PortOpt struct {
  17. ports []swarm.PortConfig
  18. }
  19. // Set a new port value
  20. func (p *PortOpt) Set(value string) error {
  21. csvReader := csv.NewReader(strings.NewReader(value))
  22. fields, err := csvReader.Read()
  23. if err != nil {
  24. return err
  25. }
  26. pConfig := swarm.PortConfig{}
  27. for _, field := range fields {
  28. parts := strings.SplitN(field, "=", 2)
  29. if len(parts) != 2 {
  30. return fmt.Errorf("invalid field %s", field)
  31. }
  32. key := strings.ToLower(parts[0])
  33. value := strings.ToLower(parts[1])
  34. switch key {
  35. case portOptProtocol:
  36. if value != string(swarm.PortConfigProtocolTCP) && value != string(swarm.PortConfigProtocolUDP) {
  37. return fmt.Errorf("invalid protocol value %s", value)
  38. }
  39. pConfig.Protocol = swarm.PortConfigProtocol(value)
  40. case portOptMode:
  41. if value != string(swarm.PortConfigPublishModeIngress) && value != string(swarm.PortConfigPublishModeHost) {
  42. return fmt.Errorf("invalid publish mode value %s", value)
  43. }
  44. pConfig.PublishMode = swarm.PortConfigPublishMode(value)
  45. case portOptTargetPort:
  46. tPort, err := strconv.ParseUint(value, 10, 16)
  47. if err != nil {
  48. return err
  49. }
  50. pConfig.TargetPort = uint32(tPort)
  51. case portOptPublishedPort:
  52. pPort, err := strconv.ParseUint(value, 10, 16)
  53. if err != nil {
  54. return err
  55. }
  56. pConfig.PublishedPort = uint32(pPort)
  57. default:
  58. return fmt.Errorf("invalid field key %s", key)
  59. }
  60. }
  61. if pConfig.TargetPort == 0 {
  62. return fmt.Errorf("missing mandatory field %q", portOptTargetPort)
  63. }
  64. p.ports = append(p.ports, pConfig)
  65. return nil
  66. }
  67. // Type returns the type of this option
  68. func (p *PortOpt) Type() string {
  69. return "port"
  70. }
  71. // String returns a string repr of this option
  72. func (p *PortOpt) String() string {
  73. ports := []string{}
  74. for _, port := range p.ports {
  75. repr := fmt.Sprintf("%v:%v/%s/%s", port.PublishedPort, port.TargetPort, port.Protocol, port.PublishMode)
  76. ports = append(ports, repr)
  77. }
  78. return strings.Join(ports, ", ")
  79. }
  80. // Value returns the ports
  81. func (p *PortOpt) Value() []swarm.PortConfig {
  82. return p.ports
  83. }