package opts import ( "encoding/csv" "fmt" "regexp" "strings" ) const ( networkOptName = "name" networkOptAlias = "alias" driverOpt = "driver-opt" ) // NetworkAttachmentOpts represents the network options for endpoint creation type NetworkAttachmentOpts struct { Target string Aliases []string DriverOpts map[string]string } // NetworkOpt represents a network config in swarm mode. type NetworkOpt struct { options []NetworkAttachmentOpts } // Set networkopts value func (n *NetworkOpt) Set(value string) error { longSyntax, err := regexp.MatchString(`\w+=\w+(,\w+=\w+)*`, value) if err != nil { return err } var netOpt NetworkAttachmentOpts if longSyntax { csvReader := csv.NewReader(strings.NewReader(value)) fields, err := csvReader.Read() if err != nil { return err } netOpt.Aliases = []string{} for _, field := range fields { parts := strings.SplitN(field, "=", 2) if len(parts) < 2 { return fmt.Errorf("invalid field %s", field) } key := strings.TrimSpace(strings.ToLower(parts[0])) value := strings.TrimSpace(strings.ToLower(parts[1])) switch key { case networkOptName: netOpt.Target = value case networkOptAlias: netOpt.Aliases = append(netOpt.Aliases, value) case driverOpt: key, value, err = parseDriverOpt(value) if err == nil { if netOpt.DriverOpts == nil { netOpt.DriverOpts = make(map[string]string) } netOpt.DriverOpts[key] = value } else { return err } default: return fmt.Errorf("invalid field key %s", key) } } if len(netOpt.Target) == 0 { return fmt.Errorf("network name/id is not specified") } } else { netOpt.Target = value } n.options = append(n.options, netOpt) return nil } // Type returns the type of this option func (n *NetworkOpt) Type() string { return "network" } // Value returns the networkopts func (n *NetworkOpt) Value() []NetworkAttachmentOpts { return n.options } // String returns the network opts as a string func (n *NetworkOpt) String() string { return "" } func parseDriverOpt(driverOpt string) (string, string, error) { parts := strings.SplitN(driverOpt, "=", 2) if len(parts) != 2 { return "", "", fmt.Errorf("invalid key value pair format in driver options") } key := strings.TrimSpace(strings.ToLower(parts[0])) value := strings.TrimSpace(strings.ToLower(parts[1])) return key, value, nil }