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