github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/opts/opts.go (about) 1 package opts 2 3 import ( 4 "fmt" 5 "net" 6 "regexp" 7 "strings" 8 ) 9 10 var ( 11 alphaRegexp = regexp.MustCompile(`[a-zA-Z]`) 12 domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`) 13 ) 14 15 // ListOpts holds a list of values and a validation function. 16 type ListOpts struct { 17 values *[]string 18 validator ValidatorFctType 19 } 20 21 // NewListOpts creates a new ListOpts with the specified validator. 22 func NewListOpts(validator ValidatorFctType) ListOpts { 23 var values []string 24 return *NewListOptsRef(&values, validator) 25 } 26 27 // NewListOptsRef creates a new ListOpts with the specified values and validator. 28 func NewListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts { 29 return &ListOpts{ 30 values: values, 31 validator: validator, 32 } 33 } 34 35 func (opts *ListOpts) String() string { 36 return fmt.Sprintf("%v", []string((*opts.values))) 37 } 38 39 // Set validates if needed the input value and add it to the 40 // internal slice. 41 func (opts *ListOpts) Set(value string) error { 42 if opts.validator != nil { 43 v, err := opts.validator(value) 44 if err != nil { 45 return err 46 } 47 value = v 48 } 49 (*opts.values) = append((*opts.values), value) 50 return nil 51 } 52 53 // Delete removes the specified element from the slice. 54 func (opts *ListOpts) Delete(key string) { 55 for i, k := range *opts.values { 56 if k == key { 57 (*opts.values) = append((*opts.values)[:i], (*opts.values)[i+1:]...) 58 return 59 } 60 } 61 } 62 63 // GetMap returns the content of values in a map in order to avoid 64 // duplicates. 65 func (opts *ListOpts) GetMap() map[string]struct{} { 66 ret := make(map[string]struct{}) 67 for _, k := range *opts.values { 68 ret[k] = struct{}{} 69 } 70 return ret 71 } 72 73 // GetAll returns the values of slice. 74 func (opts *ListOpts) GetAll() []string { 75 return (*opts.values) 76 } 77 78 // GetAllOrEmpty returns the values of the slice 79 // or an empty slice when there are no values. 80 func (opts *ListOpts) GetAllOrEmpty() []string { 81 v := *opts.values 82 if v == nil { 83 return make([]string, 0) 84 } 85 return v 86 } 87 88 // Get checks the existence of the specified key. 89 func (opts *ListOpts) Get(key string) bool { 90 for _, k := range *opts.values { 91 if k == key { 92 return true 93 } 94 } 95 return false 96 } 97 98 // Len returns the amount of element in the slice. 99 func (opts *ListOpts) Len() int { 100 return len((*opts.values)) 101 } 102 103 //MapOpts holds a map of values and a validation function. 104 type MapOpts struct { 105 values map[string]string 106 validator ValidatorFctType 107 } 108 109 // Set validates if needed the input value and add it to the 110 // internal map, by splitting on '='. 111 func (opts *MapOpts) Set(value string) error { 112 if opts.validator != nil { 113 v, err := opts.validator(value) 114 if err != nil { 115 return err 116 } 117 value = v 118 } 119 vals := strings.SplitN(value, "=", 2) 120 if len(vals) == 1 { 121 (opts.values)[vals[0]] = "" 122 } else { 123 (opts.values)[vals[0]] = vals[1] 124 } 125 return nil 126 } 127 128 // GetAll returns the values of MapOpts as a map. 129 func (opts *MapOpts) GetAll() map[string]string { 130 return opts.values 131 } 132 133 func (opts *MapOpts) String() string { 134 return fmt.Sprintf("%v", map[string]string((opts.values))) 135 } 136 137 // NewMapOpts creates a new MapOpts with the specified map of values and a validator. 138 func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts { 139 if values == nil { 140 values = make(map[string]string) 141 } 142 return &MapOpts{ 143 values: values, 144 validator: validator, 145 } 146 } 147 148 // ValidatorFctType defines a validator function that returns a validated string and/or an error. 149 type ValidatorFctType func(val string) (string, error) 150 151 // ValidatorFctListType defines a validator function that returns a validated list of string and/or an error 152 type ValidatorFctListType func(val string) ([]string, error) 153 154 // ValidateIPAddress validates an Ip address. 155 func ValidateIPAddress(val string) (string, error) { 156 var ip = net.ParseIP(strings.TrimSpace(val)) 157 if ip != nil { 158 return ip.String(), nil 159 } 160 return "", fmt.Errorf("%s is not an ip address", val) 161 } 162 163 // ValidateDNSSearch validates domain for resolvconf search configuration. 164 // A zero length domain is represented by a dot (.). 165 func ValidateDNSSearch(val string) (string, error) { 166 if val = strings.Trim(val, " "); val == "." { 167 return val, nil 168 } 169 return validateDomain(val) 170 } 171 172 func validateDomain(val string) (string, error) { 173 if alphaRegexp.FindString(val) == "" { 174 return "", fmt.Errorf("%s is not a valid domain", val) 175 } 176 ns := domainRegexp.FindSubmatch([]byte(val)) 177 if len(ns) > 0 && len(ns[1]) < 255 { 178 return string(ns[1]), nil 179 } 180 return "", fmt.Errorf("%s is not a valid domain", val) 181 } 182 183 // ValidateLabel validates that the specified string is a valid label, and returns it. 184 // Labels are in the form on key=value. 185 func ValidateLabel(val string) (string, error) { 186 if strings.Count(val, "=") < 1 { 187 return "", fmt.Errorf("bad attribute format: %s", val) 188 } 189 return val, nil 190 }