normalizeAndValidateLabel canonicalizes a single label and rejects it if it would violate the labels invariants: - lowercase - charset `[a-z0-9:_-]+` (colon allowed for namespacing, but only the server may set `e2a:*`) - 1..MaxLabelLength chars after trimming Returns the normalized form on success.
(raw string, allowSystemPrefix bool)
| 1456 | // transformation — colons / dashes / underscores stay as-is so a label |
| 1457 | // from a query param is byte-identical to the same label set via PATCH. |
| 1458 | func normalizeAndValidateLabel(raw string, allowSystemPrefix bool) (string, error) { |
| 1459 | l := strings.ToLower(strings.TrimSpace(raw)) |
| 1460 | if l == "" { |
| 1461 | return "", errors.New("label must not be empty") |
| 1462 | } |
| 1463 | if len(l) > MaxLabelLength { |
| 1464 | return "", fmt.Errorf("label too long (max %d chars)", MaxLabelLength) |
| 1465 | } |
| 1466 | for _, r := range l { |
| 1467 | switch { |
| 1468 | case r >= 'a' && r <= 'z': |
| 1469 | case r >= '0' && r <= '9': |
| 1470 | case r == '-' || r == '_' || r == ':': |
| 1471 | default: |
| 1472 | return "", fmt.Errorf("label %q has invalid character; allowed: a-z 0-9 : - _", l) |
| 1473 | } |
| 1474 | } |
| 1475 | if !allowSystemPrefix && strings.HasPrefix(l, LabelSystemPrefix) { |
| 1476 | return "", fmt.Errorf("labels starting with %q are reserved for system use", LabelSystemPrefix) |
| 1477 | } |
| 1478 | return l, nil |
| 1479 | } |
| 1480 | |
| 1481 | // NormalizeAndValidateLabelList runs each entry through |
| 1482 | // normalizeAndValidateLabel, dedups within the slice, and rejects if |
no outgoing calls
no test coverage detected