github.com/itscaro/cli@v0.0.0-20190705081621-c9db0fe93829/opts/network.go (about) 1 package opts 2 3 import ( 4 "encoding/csv" 5 "fmt" 6 "regexp" 7 "strings" 8 ) 9 10 const ( 11 networkOptName = "name" 12 networkOptAlias = "alias" 13 driverOpt = "driver-opt" 14 ) 15 16 // NetworkAttachmentOpts represents the network options for endpoint creation 17 type NetworkAttachmentOpts struct { 18 Target string 19 Aliases []string 20 DriverOpts map[string]string 21 Links []string // TODO add support for links in the csv notation of `--network` 22 IPv4Address string // TODO add support for IPv4-address in the csv notation of `--network` 23 IPv6Address string // TODO add support for IPv6-address in the csv notation of `--network` 24 LinkLocalIPs []string // TODO add support for LinkLocalIPs in the csv notation of `--network` ? 25 } 26 27 // NetworkOpt represents a network config in swarm mode. 28 type NetworkOpt struct { 29 options []NetworkAttachmentOpts 30 } 31 32 // Set networkopts value 33 func (n *NetworkOpt) Set(value string) error { 34 longSyntax, err := regexp.MatchString(`\w+=\w+(,\w+=\w+)*`, value) 35 if err != nil { 36 return err 37 } 38 39 var netOpt NetworkAttachmentOpts 40 if longSyntax { 41 csvReader := csv.NewReader(strings.NewReader(value)) 42 fields, err := csvReader.Read() 43 if err != nil { 44 return err 45 } 46 47 netOpt.Aliases = []string{} 48 for _, field := range fields { 49 parts := strings.SplitN(field, "=", 2) 50 51 if len(parts) < 2 { 52 return fmt.Errorf("invalid field %s", field) 53 } 54 55 key := strings.TrimSpace(strings.ToLower(parts[0])) 56 value := strings.TrimSpace(strings.ToLower(parts[1])) 57 58 switch key { 59 case networkOptName: 60 netOpt.Target = value 61 case networkOptAlias: 62 netOpt.Aliases = append(netOpt.Aliases, value) 63 case driverOpt: 64 key, value, err = parseDriverOpt(value) 65 if err == nil { 66 if netOpt.DriverOpts == nil { 67 netOpt.DriverOpts = make(map[string]string) 68 } 69 netOpt.DriverOpts[key] = value 70 } else { 71 return err 72 } 73 default: 74 return fmt.Errorf("invalid field key %s", key) 75 } 76 } 77 if len(netOpt.Target) == 0 { 78 return fmt.Errorf("network name/id is not specified") 79 } 80 } else { 81 netOpt.Target = value 82 } 83 n.options = append(n.options, netOpt) 84 return nil 85 } 86 87 // Type returns the type of this option 88 func (n *NetworkOpt) Type() string { 89 return "network" 90 } 91 92 // Value returns the networkopts 93 func (n *NetworkOpt) Value() []NetworkAttachmentOpts { 94 return n.options 95 } 96 97 // String returns the network opts as a string 98 func (n *NetworkOpt) String() string { 99 return "" 100 } 101 102 // NetworkMode return the network mode for the network option 103 func (n *NetworkOpt) NetworkMode() string { 104 networkIDOrName := "default" 105 netOptVal := n.Value() 106 if len(netOptVal) > 0 { 107 networkIDOrName = netOptVal[0].Target 108 } 109 return networkIDOrName 110 } 111 112 func parseDriverOpt(driverOpt string) (string, string, error) { 113 parts := strings.SplitN(driverOpt, "=", 2) 114 if len(parts) != 2 { 115 return "", "", fmt.Errorf("invalid key value pair format in driver options") 116 } 117 key := strings.TrimSpace(strings.ToLower(parts[0])) 118 value := strings.TrimSpace(strings.ToLower(parts[1])) 119 return key, value, nil 120 }