diff --git a/pkg/apis/provisioning/v1alpha5/provisioner_validation.go b/pkg/apis/provisioning/v1alpha5/provisioner_validation.go index d863c2c7da0f..a1c816772363 100644 --- a/pkg/apis/provisioning/v1alpha5/provisioner_validation.go +++ b/pkg/apis/provisioning/v1alpha5/provisioner_validation.go @@ -98,10 +98,30 @@ func (c *Constraints) validateLabels() (errs *apis.FieldError) { if known, ok := WellKnownLabels[key]; ok && !functional.ContainsString(known, value) { errs = errs.Also(apis.ErrInvalidValue(fmt.Sprintf("%s not in %s", value, known), fmt.Sprintf("labels[%s]", key))) } + if _, ok := WellKnownLabels[key]; !ok && IsRestrictedLabelDomain(key) { + errs = errs.Also(apis.ErrInvalidKeyName(key, "labels", "label prefix not supported")) + } } return errs } +func IsRestrictedLabelDomain(key string) bool { + labelDomain := getLabelDomain(key) + for _, restrictedLabelDomain := range RestrictedLabelDomains { + if strings.HasSuffix(labelDomain, restrictedLabelDomain) { + return true + } + } + return false +} + +func getLabelDomain(key string) string { + if parts := strings.SplitN(key, "/", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + func (c *Constraints) validateTaints() (errs *apis.FieldError) { for i, taint := range c.Taints { // Validate Key diff --git a/pkg/apis/provisioning/v1alpha5/provisioner_validation_test.go b/pkg/apis/provisioning/v1alpha5/provisioner_validation_test.go index 53381c2a7dd7..953181880f25 100644 --- a/pkg/apis/provisioning/v1alpha5/provisioner_validation_test.go +++ b/pkg/apis/provisioning/v1alpha5/provisioner_validation_test.go @@ -77,6 +77,12 @@ var _ = Describe("Validation", func() { Expect(provisioner.Validate(ctx)).ToNot(Succeed()) } }) + It("should fail for restricted prefixes when not well known labels", func() { + for _, label := range RestrictedLabelDomains { + provisioner.Spec.Labels = map[string]string{label + "/unknown": randomdata.SillyName()} + Expect(provisioner.Validate(ctx)).ToNot(Succeed()) + } + }) It("should succeed for well known label values", func() { WellKnownLabels[v1.LabelTopologyZone] = []string{"test-1", "test1"} WellKnownLabels[v1.LabelInstanceTypeStable] = []string{"test-1", "test1"} diff --git a/pkg/apis/provisioning/v1alpha5/register.go b/pkg/apis/provisioning/v1alpha5/register.go index 82e244893255..fdc8185a6bc7 100644 --- a/pkg/apis/provisioning/v1alpha5/register.go +++ b/pkg/apis/provisioning/v1alpha5/register.go @@ -52,6 +52,12 @@ var ( v1.LabelArchStable: {}, v1.LabelOSStable: {}, } + // These are either prohibited by the kubelet or reserved by karpenter + RestrictedLabelDomains = []string{ + "kubernetes.io", + "k8s.io", + "karpenter.sh", + } DefaultHook = func(ctx context.Context, constraints *Constraints) {} ValidateHook = func(ctx context.Context, constraints *Constraints) *apis.FieldError { return nil } ) diff --git a/pkg/cloudprovider/aws/apis/v1alpha1/register.go b/pkg/cloudprovider/aws/apis/v1alpha1/register.go index 0266de42e080..acb985a0e081 100644 --- a/pkg/cloudprovider/aws/apis/v1alpha1/register.go +++ b/pkg/cloudprovider/aws/apis/v1alpha1/register.go @@ -31,6 +31,9 @@ var ( "x86_64": v1alpha5.ArchitectureAmd64, v1alpha5.ArchitectureArm64: v1alpha5.ArchitectureArm64, } + AWSRestrictedLabelDomains = []string{ + "k8s.aws", + } ) var ( @@ -42,4 +45,5 @@ func init() { Scheme.AddKnownTypes(schema.GroupVersion{Group: v1alpha5.ExtensionsGroup, Version: "v1alpha1"}, &AWS{}) v1alpha5.RestrictedLabels = append(v1alpha5.RestrictedLabels, AWSLabelPrefix) v1alpha5.WellKnownLabels[CapacityTypeLabel] = []string{CapacityTypeSpot, CapacityTypeOnDemand} + v1alpha5.RestrictedLabelDomains = append(v1alpha5.RestrictedLabelDomains, AWSRestrictedLabelDomains...) } diff --git a/website/content/en/docs/getting-started/_index.md b/website/content/en/docs/getting-started/_index.md index 39addbddccff..9c080e3f494a 100644 --- a/website/content/en/docs/getting-started/_index.md +++ b/website/content/en/docs/getting-started/_index.md @@ -190,7 +190,7 @@ metadata: name: default spec: requirements: - - key: node.k8s.io/capacity-type + - key: node.k8s.aws/capacity-type operator: In values: ["spot"] provider: