mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-06-12 00:19:24 +00:00
fix(config): allow @ . : / in context names
Real kubeconfig context names commonly contain characters the validator rejected: - 'admin@home', 'user@cluster.example.com' (kubectl rename, EKS aws-iam-authenticator) - 'cluster.example.com', 'gke_proj_zone_cluster.prod' (FQDN, GKE) - 'arn:aws:eks:us-east-1:123:cluster/foo' (EKS ARN) kubeconfig itself imposes no character restrictions, so requiring [a-zA-Z0-9_-] only was kportal-specific over-validation that blocked legitimate users. Widen the allowed set to add '@', '.', ':', '/'. Names must still start and end with a letter or digit so YAML specials and leading whitespace remain rejected. Tests cover the new positive cases and tighten negative coverage (starts-with-@, ends-with-/, ends-with-dot).
This commit is contained in:
@@ -26,9 +26,15 @@ var (
|
||||
// A series of DNS labels separated by dots (no consecutive dots allowed)
|
||||
dns1123SubdomainRegexp = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`)
|
||||
|
||||
// contextNameRegexp matches valid context names
|
||||
// Allows alphanumeric characters, hyphens, and underscores (to support various kubeconfig naming conventions)
|
||||
contextNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$`)
|
||||
// contextNameRegexp matches valid kubeconfig context names.
|
||||
// kubeconfig itself imposes no character restriction; we accept the union
|
||||
// of common naming conventions seen in the wild:
|
||||
// - hyphens / underscores: minikube, docker-desktop, gke_proj_zone_cluster
|
||||
// - "@": user@cluster (kubectl rename, EKS aws-iam-authenticator)
|
||||
// - ".": cluster.example.com, GKE dotted names
|
||||
// - ":" and "/": EKS ARNs (arn:aws:eks:us-east-1:123:cluster/foo)
|
||||
// Must start and end with an alphanumeric character.
|
||||
contextNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9._:/@_-]*[a-zA-Z0-9])?$`)
|
||||
|
||||
// validResourceTypes contains the allowed Kubernetes resource types
|
||||
validResourceTypes = []string{"pod", "service"}
|
||||
@@ -571,7 +577,7 @@ func validateContextName(name, field string) *ValidationError {
|
||||
if !contextNameRegexp.MatchString(name) {
|
||||
return &ValidationError{
|
||||
Field: field,
|
||||
Message: fmt.Sprintf("Context name '%s' is not valid (must consist of alphanumeric characters, hyphens, or underscores, and start/end with alphanumeric)", name),
|
||||
Message: fmt.Sprintf("Context name '%s' is not valid (allowed: letters, digits, hyphens, underscores, dots, '@', ':', '/'; must start and end with a letter or digit)", name),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1524,7 +1524,7 @@ func TestValidator_ValidateContextAndNamespaceNames(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectErrors: true,
|
||||
errorContains: []string{"not valid", "alphanumeric"},
|
||||
errorContains: []string{"not valid", "letter or digit"},
|
||||
},
|
||||
{
|
||||
name: "context name too long",
|
||||
@@ -1560,7 +1560,7 @@ func TestValidator_ValidateContextAndNamespaceNames(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectErrors: true,
|
||||
errorContains: []string{"not valid", "start/end with alphanumeric"},
|
||||
errorContains: []string{"not valid", "letter or digit"},
|
||||
},
|
||||
{
|
||||
name: "invalid context name ends with underscore",
|
||||
@@ -1578,7 +1578,7 @@ func TestValidator_ValidateContextAndNamespaceNames(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectErrors: true,
|
||||
errorContains: []string{"not valid", "start/end with alphanumeric"},
|
||||
errorContains: []string{"not valid", "letter or digit"},
|
||||
},
|
||||
{
|
||||
name: "invalid namespace name with spaces",
|
||||
@@ -1893,6 +1893,11 @@ func TestValidateContextName(t *testing.T) {
|
||||
{name: "valid single char", contextName: "a", errorMsg: "", expectError: false},
|
||||
{name: "valid single digit", contextName: "1", errorMsg: "", expectError: false},
|
||||
{name: "valid starts with digit", contextName: "123-cluster", errorMsg: "", expectError: false},
|
||||
{name: "valid user@cluster", contextName: "admin@home", errorMsg: "", expectError: false},
|
||||
{name: "valid user@fqdn", contextName: "user@cluster.example.com", errorMsg: "", expectError: false},
|
||||
{name: "valid dotted FQDN", contextName: "cluster.example.com", errorMsg: "", expectError: false},
|
||||
{name: "valid GKE dotted", contextName: "gke_proj_zone_cluster.prod", errorMsg: "", expectError: false},
|
||||
{name: "valid EKS ARN", contextName: "arn:aws:eks:us-east-1:123:cluster/foo", errorMsg: "", expectError: false},
|
||||
|
||||
// Invalid cases
|
||||
{name: "invalid empty", contextName: "", errorMsg: "not valid", expectError: true},
|
||||
@@ -1900,10 +1905,10 @@ func TestValidateContextName(t *testing.T) {
|
||||
{name: "invalid ends with hyphen", contextName: "cluster-", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid starts with underscore", contextName: "_cluster", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid ends with underscore", contextName: "cluster_", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid starts with @", contextName: "@cluster", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid ends with /", contextName: "cluster/", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid ends with .", contextName: "cluster.", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid with spaces", contextName: "my cluster", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid with dots", contextName: "my.cluster", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid with special chars", contextName: "cluster@123", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid with slash", contextName: "cluster/name", errorMsg: "not valid", expectError: true},
|
||||
{name: "invalid too long", contextName: strings.Repeat("a", 254), errorMsg: "exceeds maximum length", expectError: true},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user