mirror of https://github.com/k3s-io/k3s
Updating namespaces to be DNS labels instead of DNS names.
parent
969023f3ec
commit
d10af89493
|
@ -51,7 +51,7 @@ type Namespace struct {
|
|||
}
|
||||
```
|
||||
|
||||
A *Namespace* name is a DNS compatible subdomain.
|
||||
A *Namespace* name is a DNS compatible label.
|
||||
|
||||
A *Namespace* must exist prior to associating content with it.
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ type ObjectMeta struct {
|
|||
// equivalent to the "default" namespace, but "default" is the canonical representation.
|
||||
// Not all objects are required to be scoped to a namespace - the value of this field for
|
||||
// those objects will be empty.
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace of the object; cannot be updated"`
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace of the object; must be a DNS_LABEL; cannot be updated"`
|
||||
|
||||
// SelfLink is a URL representing this object.
|
||||
SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"`
|
||||
|
|
|
@ -574,7 +574,7 @@ type TypeMeta struct {
|
|||
SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"`
|
||||
ResourceVersion uint64 `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://docs.k8s.io/api-conventions.md#concurrency-control-and-consistency"`
|
||||
APIVersion string `json:"apiVersion,omitempty" description:"version of the schema the object should have"`
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace to which the object belongs; must be a DNS_SUBDOMAIN; 'default' by default; cannot be updated"`
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace to which the object belongs; must be a DNS_LABEL; 'default' by default; cannot be updated"`
|
||||
|
||||
// DeletionTimestamp is the time after which this resource will be deleted. This
|
||||
// field is set by the server when a graceful deletion is requested by the user, and is not
|
||||
|
|
|
@ -572,7 +572,7 @@ type TypeMeta struct {
|
|||
SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"`
|
||||
ResourceVersion uint64 `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://docs.k8s.io/api-conventions.md#concurrency-control-and-consistency"`
|
||||
APIVersion string `json:"apiVersion,omitempty" description:"version of the schema the object should have"`
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace to which the object belongs; must be a DNS_SUBDOMAIN; 'default' by default; cannot be updated"`
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace to which the object belongs; must be a DNS_LABEL; 'default' by default; cannot be updated"`
|
||||
|
||||
// DeletionTimestamp is the time after which this resource will be deleted. This
|
||||
// field is set by the server when a graceful deletion is requested by the user, and is not
|
||||
|
|
|
@ -99,7 +99,7 @@ type ObjectMeta struct {
|
|||
// equivalent to the "default" namespace, but "default" is the canonical representation.
|
||||
// Not all objects are required to be scoped to a namespace - the value of this field for
|
||||
// those objects will be empty.
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace of the object; cannot be updated"`
|
||||
Namespace string `json:"namespace,omitempty" description:"namespace of the object; must be a DNS_LABEL; cannot be updated"`
|
||||
|
||||
// SelfLink is a URL representing this object.
|
||||
SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"`
|
||||
|
|
|
@ -126,7 +126,7 @@ func ValidateNodeName(name string, prefix bool) (bool, string) {
|
|||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
func ValidateNamespaceName(name string, prefix bool) (bool, string) {
|
||||
return nameIsDNSSubdomain(name, prefix)
|
||||
return nameIsDNSLabel(name, prefix)
|
||||
}
|
||||
|
||||
// ValidateLimitRangeName can be used to check whether the given limit range name is valid.
|
||||
|
@ -176,6 +176,17 @@ func nameIsDNSSubdomain(name string, prefix bool) (bool, string) {
|
|||
return false, dnsSubdomainErrorMsg
|
||||
}
|
||||
|
||||
// nameIsDNSLabel is a ValidateNameFunc for names that must be a DNS 1123 label.
|
||||
func nameIsDNSLabel(name string, prefix bool) (bool, string) {
|
||||
if prefix {
|
||||
name = maskTrailingDash(name)
|
||||
}
|
||||
if util.IsDNS1123Label(name) {
|
||||
return true, ""
|
||||
}
|
||||
return false, dns1123LabelErrorMsg
|
||||
}
|
||||
|
||||
// nameIsDNS952Label is a ValidateNameFunc for names that must be a DNS 952 label.
|
||||
func nameIsDNS952Label(name string, prefix bool) (bool, string) {
|
||||
if prefix {
|
||||
|
@ -210,8 +221,8 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val
|
|||
if requiresNamespace {
|
||||
if len(meta.Namespace) == 0 {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("namespace"))
|
||||
} else if !util.IsDNS1123Subdomain(meta.Namespace) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", meta.Namespace, dnsSubdomainErrorMsg))
|
||||
} else if ok, _ := ValidateNamespaceName(meta.Namespace, false); !ok {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", meta.Namespace, dns1123LabelErrorMsg))
|
||||
}
|
||||
} else {
|
||||
if len(meta.Namespace) != 0 {
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package validation
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -54,6 +55,34 @@ func TestValidateObjectMetaCustomName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure namespace names follow dns label format
|
||||
func TestValidateObjectMetaNamespaces(t *testing.T) {
|
||||
errs := ValidateObjectMeta(&api.ObjectMeta{Name: "test", Namespace: "foo.bar"}, false, func(s string, prefix bool) (bool, string) {
|
||||
return true, ""
|
||||
})
|
||||
if len(errs) != 1 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if !strings.Contains(errs[0].Error(), "invalid value 'foo.bar'") {
|
||||
t.Errorf("unexpected error message: %v", errs)
|
||||
}
|
||||
maxLength := 63
|
||||
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
b := make([]rune, maxLength+1)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
errs = ValidateObjectMeta(&api.ObjectMeta{Name: "test", Namespace: string(b)}, false, func(s string, prefix bool) (bool, string) {
|
||||
return true, ""
|
||||
})
|
||||
if len(errs) != 1 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if !strings.Contains(errs[0].Error(), "invalid value") {
|
||||
t.Errorf("unexpected error message: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) {
|
||||
if errs := ValidateObjectMetaUpdate(
|
||||
&api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))},
|
||||
|
@ -2517,7 +2546,7 @@ func TestValidateLimitRange(t *testing.T) {
|
|||
},
|
||||
"invalid Namespace": {
|
||||
api.LimitRange{ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "^Invalid"}, Spec: spec},
|
||||
dnsSubdomainErrorMsg,
|
||||
dns1123LabelErrorMsg,
|
||||
},
|
||||
}
|
||||
for k, v := range errorCases {
|
||||
|
@ -2584,7 +2613,7 @@ func TestValidateResourceQuota(t *testing.T) {
|
|||
},
|
||||
"invalid Namespace": {
|
||||
api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "^Invalid"}, Spec: spec},
|
||||
dnsSubdomainErrorMsg,
|
||||
dns1123LabelErrorMsg,
|
||||
},
|
||||
}
|
||||
for k, v := range errorCases {
|
||||
|
@ -2992,7 +3021,7 @@ func TestValidateEndpoints(t *testing.T) {
|
|||
"invalid namespace": {
|
||||
endpoints: api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "mysvc", Namespace: "no@#invalid.;chars\"allowed"}},
|
||||
errorType: "FieldValueInvalid",
|
||||
errorDetail: dnsSubdomainErrorMsg,
|
||||
errorDetail: dns1123LabelErrorMsg,
|
||||
},
|
||||
"invalid name": {
|
||||
endpoints: api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "-_Invliad^&Characters", Namespace: "namespace"}},
|
||||
|
|
Loading…
Reference in New Issue