Implements ControllerRevision API Object without codec and code

generation
This commit is contained in:
Kenneth Owens
2017-05-10 18:05:50 -07:00
parent 079020f559
commit ba128e6e41
83 changed files with 10233 additions and 1162 deletions

View File

@@ -32,6 +32,7 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/apis/apps:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
],
)

View File

@@ -141,3 +141,34 @@ func ValidateStatefulSetStatusUpdate(statefulSet, oldStatefulSet *apps.StatefulS
// TODO: Validate status.
return allErrs
}
// ValidateControllerRevisionName can be used to check whether the given ControllerRevision name is valid.
// Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed.
var ValidateControllerRevisionName = apivalidation.NameIsDNSSubdomain
// ValidateControllerRevision collects errors for the fields of state and returns those errors as an ErrorList. If the
// returned list is empty, state is valid. Validation is performed to ensure that state is a valid ObjectMeta, its name
// is valid, and that it doesn't exceed the MaxControllerRevisionSize.
func ValidateControllerRevision(revision *apps.ControllerRevision) field.ErrorList {
errs := field.ErrorList{}
errs = append(errs, apivalidation.ValidateObjectMeta(&revision.ObjectMeta, true, ValidateControllerRevisionName, field.NewPath("metadata"))...)
if revision.Data == nil {
errs = append(errs, field.Required(field.NewPath("data"), "data is mandatory"))
}
errs = append(errs, apivalidation.ValidateNonnegativeField(revision.Revision, field.NewPath("revision"))...)
return errs
}
// ValidateControllerRevisionUpdate collects errors pertaining to the mutation of an ControllerRevision Object. If the
// returned ErrorList is empty the update operation is valid. Any mutation to the ControllerRevision's Data or Revision
// is considered to be invalid.
func ValidateControllerRevisionUpdate(newHistory, oldHistory *apps.ControllerRevision) field.ErrorList {
errs := field.ErrorList{}
errs = append(errs, apivalidation.ValidateObjectMetaUpdate(&newHistory.ObjectMeta, &oldHistory.ObjectMeta, field.NewPath("metadata"))...)
errs = append(errs, ValidateControllerRevision(newHistory)...)
errs = append(errs, apivalidation.ValidateImmutableField(newHistory.Data, oldHistory.Data, field.NewPath("data"))...)
return errs
}

View File

@@ -21,6 +21,7 @@ import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/apps"
)
@@ -432,3 +433,159 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
}
}
}
func TestValidateControllerRevision(t *testing.T) {
newControllerRevision := func(name, namespace string, data runtime.Object, revision int64) apps.ControllerRevision {
return apps.ControllerRevision{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: data,
Revision: revision,
}
}
ss := apps.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Spec: apps.StatefulSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
Template: api.PodTemplateSpec{
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
},
},
}
var (
valid = newControllerRevision("validname", "validns", &ss, 0)
badRevision = newControllerRevision("validname", "validns", &ss, -1)
emptyName = newControllerRevision("", "validns", &ss, 0)
invalidName = newControllerRevision("NoUppercaseOrSpecialCharsLike=Equals", "validns", &ss, 0)
emptyNs = newControllerRevision("validname", "", &ss, 100)
invalidNs = newControllerRevision("validname", "NoUppercaseOrSpecialCharsLike=Equals", &ss, 100)
nilData = newControllerRevision("validname", "NoUppercaseOrSpecialCharsLike=Equals", nil, 100)
)
tests := map[string]struct {
history apps.ControllerRevision
isValid bool
}{
"valid": {valid, true},
"negative revision": {badRevision, false},
"empty name": {emptyName, false},
"invalid name": {invalidName, false},
"empty namespace": {emptyNs, false},
"invalid namespace": {invalidNs, false},
"nil data": {nilData, false},
}
for name, tc := range tests {
errs := ValidateControllerRevision(&tc.history)
if tc.isValid && len(errs) > 0 {
t.Errorf("%v: unexpected error: %v", name, errs)
}
if !tc.isValid && len(errs) == 0 {
t.Errorf("%v: unexpected non-error", name)
}
}
}
func TestValidateControllerRevisionUpdate(t *testing.T) {
newControllerRevision := func(version, name, namespace string, data runtime.Object, revision int64) apps.ControllerRevision {
return apps.ControllerRevision{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
ResourceVersion: version,
},
Data: data,
Revision: revision,
}
}
ss := apps.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Spec: apps.StatefulSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
Template: api.PodTemplateSpec{
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
},
},
}
modifiedss := apps.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "cdf", Namespace: metav1.NamespaceDefault},
Spec: apps.StatefulSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
Template: api.PodTemplateSpec{
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
},
},
}
var (
valid = newControllerRevision("1", "validname", "validns", &ss, 0)
noVersion = newControllerRevision("", "validname", "validns", &ss, 0)
changedData = newControllerRevision("1", "validname", "validns", &modifiedss, 0)
changedRevision = newControllerRevision("1", "validname", "validns", &ss, 1)
)
cases := []struct {
name string
newHistory apps.ControllerRevision
oldHistory apps.ControllerRevision
isValid bool
}{
{
name: "valid",
newHistory: valid,
oldHistory: valid,
isValid: true,
},
{
name: "invalid",
newHistory: noVersion,
oldHistory: valid,
isValid: false,
},
{
name: "changed data",
newHistory: changedData,
oldHistory: valid,
isValid: false,
},
{
name: "changed revision",
newHistory: changedRevision,
oldHistory: valid,
isValid: true,
},
}
for _, tc := range cases {
errs := ValidateControllerRevisionUpdate(&tc.newHistory, &tc.oldHistory)
if tc.isValid && len(errs) > 0 {
t.Errorf("%v: unexpected error: %v", tc.name, errs)
}
if !tc.isValid && len(errs) == 0 {
t.Errorf("%v: unexpected non-error", tc.name)
}
}
}