diff --git a/types/setting.go b/types/setting.go index ea789b0b6e..05dcb4c31e 100644 --- a/types/setting.go +++ b/types/setting.go @@ -1437,54 +1437,55 @@ func getDefaultSettingFromYAML(defaultSettingYAMLData []byte) (map[string]string return defaultSettings, nil } -func ValidateAndUnmarshalToleration(s string) (*v1.Toleration, error) { - toleration := &v1.Toleration{} - - // The schema should be `key=value:effect` or `key:effect` - s = strings.Trim(s, " ") - parts := strings.Split(s, ":") - if len(parts) != 2 { - return nil, fmt.Errorf("invalid toleration setting %v: should contain both effect and key/value pair", s) - } +func UnmarshalTolerations(tolerationSetting string) ([]v1.Toleration, error) { + taintToleration := []v1.Toleration{} - effect := v1.TaintEffect(strings.Trim(parts[1], " ")) - if effect != v1.TaintEffectNoExecute && effect != v1.TaintEffectNoSchedule && effect != v1.TaintEffectPreferNoSchedule && effect != v1.TaintEffect("") { - return nil, fmt.Errorf("invalid toleration setting %v: invalid effect", parts[1]) + tolerationSetting = strings.ReplaceAll(tolerationSetting, " ", "") + if tolerationSetting == "" { + return taintToleration, nil } - toleration.Effect = effect - if strings.Contains(parts[0], "=") { - pair := strings.Split(parts[0], "=") - if len(pair) != 2 { - return nil, fmt.Errorf("invalid toleration setting %v: invalid key/value pair", parts[0]) + tolerationList := strings.Split(tolerationSetting, ";") + for _, toleration := range tolerationList { + toleration, err := parseToleration(toleration) + if err != nil { + return nil, errors.Wrapf(err, "failed to parse toleration: %s", toleration) } - toleration.Key = strings.Trim(pair[0], " ") - toleration.Value = strings.Trim(pair[1], " ") - toleration.Operator = v1.TolerationOpEqual - } else { - toleration.Key = strings.Trim(parts[0], " ") - toleration.Operator = v1.TolerationOpExists + taintToleration = append(taintToleration, *toleration) } - - return toleration, nil + return taintToleration, nil } -func UnmarshalTolerations(tolerationSetting string) ([]v1.Toleration, error) { - res := []v1.Toleration{} +func parseToleration(taintToleration string) (*v1.Toleration, error) { + // The schema should be `key=value:effect` or `key:effect` + parts := strings.Split(taintToleration, ":") + if len(parts) != 2 { + return nil, fmt.Errorf("missing key/value and effect pair") + } - tolerationSetting = strings.Trim(tolerationSetting, " ") - if tolerationSetting != "" { - tolerationList := strings.Split(tolerationSetting, ";") - for _, t := range tolerationList { - toleration, err := ValidateAndUnmarshalToleration(t) - if err != nil { - return nil, err - } - res = append(res, *toleration) - } + // parse `key=value` or `key` + key, value, operator := "", "", v1.TolerationOperator("") + pair := strings.Split(parts[0], "=") + switch len(pair) { + case 1: + key, value, operator = parts[0], "", v1.TolerationOpExists + case 2: + key, value, operator = pair[0], pair[1], v1.TolerationOpEqual + } + + effect := v1.TaintEffect(parts[1]) + switch effect { + case "", v1.TaintEffectNoExecute, v1.TaintEffectNoSchedule, v1.TaintEffectPreferNoSchedule: + default: + return nil, fmt.Errorf("invalid effect: %v", parts[1]) } - return res, nil + return &v1.Toleration{ + Key: key, + Value: value, + Operator: operator, + Effect: effect, + }, nil } func validateAndUnmarshalLabel(label string) (key, value string, err error) {