Clean up brace whitespace in **/validation_test.go
This was making my eyes bleed as I read over code. I used the following in vim. I made them up on the fly, but they seemed to pass manual inspection. :g/},\n\s*{$/s//}, {/ :w :g/{$\n\s*{$/s//{{/ :w :g/^\(\s*\)},\n\1},$/s//}},/ :w :g/^\(\s*\)},$\n\1}$/s//}}/ :w
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -28,96 +28,84 @@ func TestValidateServerStorageVersion(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
ssv apiserverinternal.ServerStorageVersion
|
ssv apiserverinternal.ServerStorageVersion
|
||||||
expectedErr string
|
expectedErr string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "-fea",
|
APIServerID: "-fea",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
DecodableVersions: []string{"v1alpha1", "v1"},
|
DecodableVersions: []string{"v1alpha1", "v1"},
|
||||||
},
|
},
|
||||||
expectedErr: "apiServerID: Invalid value",
|
expectedErr: "apiServerID: Invalid value",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
DecodableVersions: []string{"v1beta1", "v1"},
|
DecodableVersions: []string{"v1beta1", "v1"},
|
||||||
},
|
},
|
||||||
expectedErr: "decodableVersions must include encodingVersion",
|
expectedErr: "decodableVersions must include encodingVersion",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
DecodableVersions: []string{"v1alpha1", "v1", "-fea"},
|
DecodableVersions: []string{"v1alpha1", "v1", "-fea"},
|
||||||
},
|
},
|
||||||
expectedErr: "decodableVersions[2]: Invalid value",
|
expectedErr: "decodableVersions[2]: Invalid value",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
DecodableVersions: []string{"v1alpha1", "v1"},
|
DecodableVersions: []string{"v1alpha1", "v1"},
|
||||||
},
|
},
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "mygroup.com/v2",
|
EncodingVersion: "mygroup.com/v2",
|
||||||
DecodableVersions: []string{"v1alpha1", "v1", "mygroup.com/v2"},
|
DecodableVersions: []string{"v1alpha1", "v1", "mygroup.com/v2"},
|
||||||
},
|
},
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "mygroup.com/v2",
|
EncodingVersion: "mygroup.com/v2",
|
||||||
DecodableVersions: []string{"mygroup.com/v2", "/v3"},
|
DecodableVersions: []string{"mygroup.com/v2", "/v3"},
|
||||||
},
|
},
|
||||||
expectedErr: `[].decodableVersions[1]: Invalid value: "/v3": group part: must be non-empty`,
|
expectedErr: `[].decodableVersions[1]: Invalid value: "/v3": group part: must be non-empty`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "mygroup.com/v2",
|
EncodingVersion: "mygroup.com/v2",
|
||||||
DecodableVersions: []string{"mygroup.com/v2", "mygroup.com/"},
|
DecodableVersions: []string{"mygroup.com/v2", "mygroup.com/"},
|
||||||
},
|
},
|
||||||
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/": version part: must be non-empty`,
|
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/": version part: must be non-empty`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "/v3",
|
EncodingVersion: "/v3",
|
||||||
DecodableVersions: []string{"mygroup.com/v2", "/v3"},
|
DecodableVersions: []string{"mygroup.com/v2", "/v3"},
|
||||||
},
|
},
|
||||||
expectedErr: `[].encodingVersion: Invalid value: "/v3": group part: must be non-empty`,
|
expectedErr: `[].encodingVersion: Invalid value: "/v3": group part: must be non-empty`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "v1",
|
EncodingVersion: "v1",
|
||||||
DecodableVersions: []string{"v1", "mygroup_com/v2"},
|
DecodableVersions: []string{"v1", "mygroup_com/v2"},
|
||||||
},
|
},
|
||||||
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup_com/v2": group part: a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`,
|
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup_com/v2": group part: a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "v1",
|
EncodingVersion: "v1",
|
||||||
DecodableVersions: []string{"v1", "mygroup.com/v2_"},
|
DecodableVersions: []string{"v1", "mygroup.com/v2_"},
|
||||||
},
|
},
|
||||||
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2_": version part: a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?')`,
|
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2_": version part: a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?')`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ssv: apiserverinternal.ServerStorageVersion{
|
ssv: apiserverinternal.ServerStorageVersion{
|
||||||
APIServerID: "fea",
|
APIServerID: "fea",
|
||||||
EncodingVersion: "v1",
|
EncodingVersion: "v1",
|
||||||
DecodableVersions: []string{"v1", "mygroup.com/v2/myresource"},
|
DecodableVersions: []string{"v1", "mygroup.com/v2/myresource"},
|
||||||
},
|
},
|
||||||
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2/myresource": an apiVersion is a DNS-1035 label, which must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyVersion')`,
|
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2/myresource": an apiVersion is a DNS-1035 label, which must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyVersion')`,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
err := validateServerStorageVersion(tc.ssv, field.NewPath("")).ToAggregate()
|
err := validateServerStorageVersion(tc.ssv, field.NewPath("")).ToAggregate()
|
||||||
@@ -142,91 +130,70 @@ func TestValidateCommonVersion(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
status apiserverinternal.StorageVersionStatus
|
status apiserverinternal.StorageVersionStatus
|
||||||
expectedErr string
|
expectedErr string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
status: apiserverinternal.StorageVersionStatus{
|
status: apiserverinternal.StorageVersionStatus{
|
||||||
StorageVersions: []apiserverinternal.ServerStorageVersion{},
|
StorageVersions: []apiserverinternal.ServerStorageVersion{},
|
||||||
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
||||||
},
|
},
|
||||||
expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet",
|
expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
status: apiserverinternal.StorageVersionStatus{
|
status: apiserverinternal.StorageVersionStatus{
|
||||||
StorageVersions: []apiserverinternal.ServerStorageVersion{
|
StorageVersions: []apiserverinternal.ServerStorageVersion{{
|
||||||
{
|
|
||||||
APIServerID: "1",
|
APIServerID: "1",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
APIServerID: "2",
|
APIServerID: "2",
|
||||||
EncodingVersion: "v1",
|
EncodingVersion: "v1",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
||||||
},
|
},
|
||||||
expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet",
|
expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
status: apiserverinternal.StorageVersionStatus{
|
status: apiserverinternal.StorageVersionStatus{
|
||||||
StorageVersions: []apiserverinternal.ServerStorageVersion{
|
StorageVersions: []apiserverinternal.ServerStorageVersion{{
|
||||||
{
|
|
||||||
APIServerID: "1",
|
APIServerID: "1",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
APIServerID: "2",
|
APIServerID: "2",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
CommonEncodingVersion: nil,
|
CommonEncodingVersion: nil,
|
||||||
},
|
},
|
||||||
expectedErr: "Invalid value: \"null\": the common encoding version is v1alpha1",
|
expectedErr: "Invalid value: \"null\": the common encoding version is v1alpha1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
status: apiserverinternal.StorageVersionStatus{
|
status: apiserverinternal.StorageVersionStatus{
|
||||||
StorageVersions: []apiserverinternal.ServerStorageVersion{
|
StorageVersions: []apiserverinternal.ServerStorageVersion{{
|
||||||
{
|
|
||||||
APIServerID: "1",
|
APIServerID: "1",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
APIServerID: "2",
|
APIServerID: "2",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
CommonEncodingVersion: func() *string { a := "v1"; return &a }(),
|
CommonEncodingVersion: func() *string { a := "v1"; return &a }(),
|
||||||
},
|
},
|
||||||
expectedErr: "Invalid value: \"v1\": the actual common encoding version is v1alpha1",
|
expectedErr: "Invalid value: \"v1\": the actual common encoding version is v1alpha1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
status: apiserverinternal.StorageVersionStatus{
|
status: apiserverinternal.StorageVersionStatus{
|
||||||
StorageVersions: []apiserverinternal.ServerStorageVersion{
|
StorageVersions: []apiserverinternal.ServerStorageVersion{{
|
||||||
{
|
|
||||||
APIServerID: "1",
|
APIServerID: "1",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
APIServerID: "2",
|
APIServerID: "2",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
||||||
},
|
},
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
status: apiserverinternal.StorageVersionStatus{
|
status: apiserverinternal.StorageVersionStatus{
|
||||||
StorageVersions: []apiserverinternal.ServerStorageVersion{
|
StorageVersions: []apiserverinternal.ServerStorageVersion{{
|
||||||
{
|
|
||||||
APIServerID: "1",
|
APIServerID: "1",
|
||||||
EncodingVersion: "v1alpha1",
|
EncodingVersion: "v1alpha1",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
|
||||||
},
|
},
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
err := validateCommonVersion(tc.status, field.NewPath(""))
|
err := validateCommonVersion(tc.status, field.NewPath(""))
|
||||||
if err == nil && len(tc.expectedErr) == 0 {
|
if err == nil && len(tc.expectedErr) == 0 {
|
||||||
@@ -250,78 +217,58 @@ func TestValidateStorageVersionCondition(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
conditions []apiserverinternal.StorageVersionCondition
|
conditions []apiserverinternal.StorageVersionCondition
|
||||||
expectedErr string
|
expectedErr string
|
||||||
}{
|
}{{
|
||||||
{
|
conditions: []apiserverinternal.StorageVersionCondition{{
|
||||||
conditions: []apiserverinternal.StorageVersionCondition{
|
|
||||||
{
|
|
||||||
Type: "-fea",
|
Type: "-fea",
|
||||||
Status: "True",
|
Status: "True",
|
||||||
Reason: "unknown",
|
Reason: "unknown",
|
||||||
Message: "unknown",
|
Message: "unknown",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
expectedErr: "type: Invalid value",
|
expectedErr: "type: Invalid value",
|
||||||
},
|
}, {
|
||||||
{
|
conditions: []apiserverinternal.StorageVersionCondition{{
|
||||||
conditions: []apiserverinternal.StorageVersionCondition{
|
|
||||||
{
|
|
||||||
Type: "fea",
|
Type: "fea",
|
||||||
Status: "-True",
|
Status: "-True",
|
||||||
Reason: "unknown",
|
Reason: "unknown",
|
||||||
Message: "unknown",
|
Message: "unknown",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
expectedErr: "status: Invalid value",
|
expectedErr: "status: Invalid value",
|
||||||
},
|
}, {
|
||||||
{
|
conditions: []apiserverinternal.StorageVersionCondition{{
|
||||||
conditions: []apiserverinternal.StorageVersionCondition{
|
|
||||||
{
|
|
||||||
Type: "fea",
|
Type: "fea",
|
||||||
Status: "True",
|
Status: "True",
|
||||||
Message: "unknown",
|
Message: "unknown",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
expectedErr: "Required value: reason cannot be empty",
|
expectedErr: "Required value: reason cannot be empty",
|
||||||
},
|
}, {
|
||||||
{
|
conditions: []apiserverinternal.StorageVersionCondition{{
|
||||||
conditions: []apiserverinternal.StorageVersionCondition{
|
|
||||||
{
|
|
||||||
Type: "fea",
|
Type: "fea",
|
||||||
Status: "True",
|
Status: "True",
|
||||||
Reason: "unknown",
|
Reason: "unknown",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
expectedErr: "Required value: message cannot be empty",
|
expectedErr: "Required value: message cannot be empty",
|
||||||
},
|
}, {
|
||||||
{
|
conditions: []apiserverinternal.StorageVersionCondition{{
|
||||||
conditions: []apiserverinternal.StorageVersionCondition{
|
|
||||||
{
|
|
||||||
Type: "fea",
|
Type: "fea",
|
||||||
Status: "True",
|
Status: "True",
|
||||||
Reason: "unknown",
|
Reason: "unknown",
|
||||||
Message: "unknown",
|
Message: "unknown",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Type: "fea",
|
Type: "fea",
|
||||||
Status: "True",
|
Status: "True",
|
||||||
Reason: "unknown",
|
Reason: "unknown",
|
||||||
Message: "unknown",
|
Message: "unknown",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
expectedErr: `"fea": the type of the condition is not unique, it also appears in conditions[0]`,
|
expectedErr: `"fea": the type of the condition is not unique, it also appears in conditions[0]`,
|
||||||
},
|
}, {
|
||||||
{
|
conditions: []apiserverinternal.StorageVersionCondition{{
|
||||||
conditions: []apiserverinternal.StorageVersionCondition{
|
|
||||||
{
|
|
||||||
Type: "fea",
|
Type: "fea",
|
||||||
Status: "True",
|
Status: "True",
|
||||||
Reason: "unknown",
|
Reason: "unknown",
|
||||||
Message: "unknown",
|
Message: "unknown",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
err := validateStorageVersionCondition(tc.conditions, field.NewPath("")).ToAggregate()
|
err := validateStorageVersionCondition(tc.conditions, field.NewPath("")).ToAggregate()
|
||||||
if err == nil && len(tc.expectedErr) == 0 {
|
if err == nil && len(tc.expectedErr) == 0 {
|
||||||
@@ -345,40 +292,31 @@ func TestValidateStorageVersionName(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
expectedErr string
|
expectedErr string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "",
|
name: "",
|
||||||
expectedErr: `name must be in the form of <group>.<resource>`,
|
expectedErr: `name must be in the form of <group>.<resource>`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "pods",
|
name: "pods",
|
||||||
expectedErr: `name must be in the form of <group>.<resource>`,
|
expectedErr: `name must be in the form of <group>.<resource>`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "core.pods",
|
name: "core.pods",
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "authentication.k8s.io.tokenreviews",
|
name: "authentication.k8s.io.tokenreviews",
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: strings.Repeat("x", 253) + ".tokenreviews",
|
name: strings.Repeat("x", 253) + ".tokenreviews",
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: strings.Repeat("x", 254) + ".tokenreviews",
|
name: strings.Repeat("x", 254) + ".tokenreviews",
|
||||||
expectedErr: `the group segment must be no more than 253 characters`,
|
expectedErr: `the group segment must be no more than 253 characters`,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "authentication.k8s.io." + strings.Repeat("x", 63),
|
name: "authentication.k8s.io." + strings.Repeat("x", 63),
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "authentication.k8s.io." + strings.Repeat("x", 64),
|
name: "authentication.k8s.io." + strings.Repeat("x", 64),
|
||||||
expectedErr: `the resource segment must be no more than 63 characters`,
|
expectedErr: `the resource segment must be no more than 63 characters`,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
errs := ValidateStorageVersionName(tc.name, false)
|
errs := ValidateStorageVersionName(tc.name, false)
|
||||||
if errs == nil && len(tc.expectedErr) == 0 {
|
if errs == nil && len(tc.expectedErr) == 0 {
|
||||||
|
@@ -248,32 +248,26 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs field.ErrorList
|
errs field.ErrorList
|
||||||
}
|
}
|
||||||
|
|
||||||
successCases := []testCase{
|
successCases := []testCase{{
|
||||||
{
|
|
||||||
name: "alpha name",
|
name: "alpha name",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakName("abc")),
|
set: mkStatefulSet(&validPodTemplate, tweakName("abc")),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "alphanumeric name",
|
name: "alphanumeric name",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakName("abc-123")),
|
set: mkStatefulSet(&validPodTemplate, tweakName("abc-123")),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "parallel pod management",
|
name: "parallel pod management",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)),
|
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ordered ready pod management",
|
name: "ordered ready pod management",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
|
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update strategy",
|
name: "update strategy",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
tweakUpdateStrategyType(apps.RollingUpdateStatefulSetStrategyType),
|
tweakUpdateStrategyType(apps.RollingUpdateStatefulSetStrategyType),
|
||||||
tweakRollingUpdatePartition(2),
|
tweakRollingUpdatePartition(2),
|
||||||
),
|
),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "PVC policy " + enableStatefulSetAutoDeletePVC,
|
name: "PVC policy " + enableStatefulSetAutoDeletePVC,
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakPVCPolicy(mkPVCPolicy(
|
tweakPVCPolicy(mkPVCPolicy(
|
||||||
@@ -281,8 +275,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType),
|
tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "maxUnavailable with parallel pod management",
|
name: "maxUnavailable with parallel pod management",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -290,8 +283,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
tweakRollingUpdatePartition(2),
|
tweakRollingUpdatePartition(2),
|
||||||
tweakMaxUnavailable(intstr.FromInt32(2)),
|
tweakMaxUnavailable(intstr.FromInt32(2)),
|
||||||
),
|
),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ordinals.start positive value",
|
name: "ordinals.start positive value",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -300,58 +292,50 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := []testCase{
|
errorCases := []testCase{{
|
||||||
{
|
|
||||||
name: "zero-length name",
|
name: "zero-length name",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakName("")),
|
set: mkStatefulSet(&validPodTemplate, tweakName("")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Required(field.NewPath("metadata", "name"), ""),
|
field.Required(field.NewPath("metadata", "name"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "name-with-dots",
|
name: "name-with-dots",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakName("abc.123")),
|
set: mkStatefulSet(&validPodTemplate, tweakName("abc.123")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), "abc.123", ""),
|
field.Invalid(field.NewPath("metadata", "name"), "abc.123", ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "long name",
|
name: "long name",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakName(strings.Repeat("a", 64))),
|
set: mkStatefulSet(&validPodTemplate, tweakName(strings.Repeat("a", 64))),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), strings.Repeat("a", 64), ""),
|
field.Invalid(field.NewPath("metadata", "name"), strings.Repeat("a", 64), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "missing-namespace",
|
name: "missing-namespace",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakNamespace("")),
|
set: mkStatefulSet(&validPodTemplate, tweakNamespace("")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Required(field.NewPath("metadata", "namespace"), ""),
|
field.Required(field.NewPath("metadata", "namespace"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "empty selector",
|
name: "empty selector",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(nil)),
|
set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(nil)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Required(field.NewPath("spec", "selector"), ""),
|
field.Required(field.NewPath("spec", "selector"), ""),
|
||||||
field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""), // selector is empty, labels are not, so select doesn't match labels
|
field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""), // selector is empty, labels are not, so select doesn't match labels
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "selector_doesnt_match",
|
name: "selector_doesnt_match",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(map[string]string{"foo": "bar"})),
|
set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(map[string]string{"foo": "bar"})),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""),
|
field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "negative_replicas",
|
name: "negative_replicas",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)),
|
set: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "replicas"), nil, ""),
|
field.Invalid(field.NewPath("spec", "replicas"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid_label",
|
name: "invalid_label",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
|
tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
|
||||||
@@ -359,8 +343,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "labels"), nil, ""),
|
field.Invalid(field.NewPath("metadata", "labels"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid_label 2",
|
name: "invalid_label 2",
|
||||||
set: mkStatefulSet(&invalidPodTemplate,
|
set: mkStatefulSet(&invalidPodTemplate,
|
||||||
tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
|
tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
|
||||||
@@ -371,8 +354,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
field.Invalid(field.NewPath("spec", "selector"), nil, ""),
|
field.Invalid(field.NewPath("spec", "selector"), nil, ""),
|
||||||
field.Invalid(field.NewPath("spec", "selector", "matchLabels"), nil, ""),
|
field.Invalid(field.NewPath("spec", "selector", "matchLabels"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid_annotation",
|
name: "invalid_annotation",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakAnnotations("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
|
tweakAnnotations("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
|
||||||
@@ -380,29 +362,25 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "annotations"), nil, ""),
|
field.Invalid(field.NewPath("metadata", "annotations"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid restart policy 1",
|
name: "invalid restart policy 1",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyOnFailure)),
|
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyOnFailure)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid restart policy 2",
|
name: "invalid restart policy 2",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyNever)),
|
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyNever)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "empty restart policy",
|
name: "empty restart policy",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy("")),
|
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy("")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid update strategy",
|
name: "invalid update strategy",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -411,8 +389,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "updateStrategy"), nil, ""),
|
field.Invalid(field.NewPath("spec", "updateStrategy"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "empty update strategy",
|
name: "empty update strategy",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -421,8 +398,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Required(field.NewPath("spec", "updateStrategy"), ""),
|
field.Required(field.NewPath("spec", "updateStrategy"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid rolling update",
|
name: "invalid rolling update",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -432,8 +408,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate"), nil, ""),
|
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "negative parition",
|
name: "negative parition",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -442,8 +417,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "partition"), nil, ""),
|
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "partition"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "empty pod management policy",
|
name: "empty pod management policy",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakPodManagementPolicy(""),
|
tweakPodManagementPolicy(""),
|
||||||
@@ -452,22 +426,19 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Required(field.NewPath("spec", "podManagementPolicy"), ""),
|
field.Required(field.NewPath("spec", "podManagementPolicy"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid pod management policy",
|
name: "invalid pod management policy",
|
||||||
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("foo")),
|
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("foo")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "podManagementPolicy"), nil, ""),
|
field.Invalid(field.NewPath("spec", "podManagementPolicy"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "set active deadline seconds",
|
name: "set active deadline seconds",
|
||||||
set: mkStatefulSet(&invalidPodTemplate2, tweakReplicas(3)),
|
set: mkStatefulSet(&invalidPodTemplate2, tweakReplicas(3)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Forbidden(field.NewPath("spec", "template", "spec", "activeDeadlineSeconds"), ""),
|
field.Forbidden(field.NewPath("spec", "template", "spec", "activeDeadlineSeconds"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "empty PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC,
|
name: "empty PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC,
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakPVCPolicy(mkPVCPolicy()),
|
tweakPVCPolicy(mkPVCPolicy()),
|
||||||
@@ -476,8 +447,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil),
|
||||||
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC,
|
name: "invalid PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC,
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakPVCPolicy(mkPVCPolicy(
|
tweakPVCPolicy(mkPVCPolicy(
|
||||||
@@ -489,8 +459,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil),
|
||||||
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil),
|
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "zero maxUnavailable",
|
name: "zero maxUnavailable",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -500,8 +469,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
|
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "zero percent maxUnavailable",
|
name: "zero percent maxUnavailable",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -511,8 +479,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
|
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "greater than 100 percent maxUnavailable",
|
name: "greater than 100 percent maxUnavailable",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -522,8 +489,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
|
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid ordinals.start",
|
name: "invalid ordinals.start",
|
||||||
set: mkStatefulSet(&validPodTemplate,
|
set: mkStatefulSet(&validPodTemplate,
|
||||||
tweakReplicas(3),
|
tweakReplicas(3),
|
||||||
@@ -635,48 +601,42 @@ func TestValidateStatefulSetStatus(t *testing.T) {
|
|||||||
observedGeneration *int64
|
observedGeneration *int64
|
||||||
collisionCount *int32
|
collisionCount *int32
|
||||||
expectedErr bool
|
expectedErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid status",
|
name: "valid status",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
expectedErr: false,
|
expectedErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid replicas",
|
name: "invalid replicas",
|
||||||
replicas: -1,
|
replicas: -1,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid readyReplicas",
|
name: "invalid readyReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: -1,
|
readyReplicas: -1,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid currentReplicas",
|
name: "invalid currentReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: -1,
|
currentReplicas: -1,
|
||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid updatedReplicas",
|
name: "invalid updatedReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
updatedReplicas: -1,
|
updatedReplicas: -1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid observedGeneration",
|
name: "invalid observedGeneration",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
@@ -684,8 +644,7 @@ func TestValidateStatefulSetStatus(t *testing.T) {
|
|||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
observedGeneration: &observedGenerationMinusOne,
|
observedGeneration: &observedGenerationMinusOne,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid collisionCount",
|
name: "invalid collisionCount",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
@@ -693,48 +652,42 @@ func TestValidateStatefulSetStatus(t *testing.T) {
|
|||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
collisionCount: &collisionCountMinusOne,
|
collisionCount: &collisionCountMinusOne,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "readyReplicas greater than replicas",
|
name: "readyReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 4,
|
readyReplicas: 4,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "currentReplicas greater than replicas",
|
name: "currentReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 4,
|
currentReplicas: 4,
|
||||||
updatedReplicas: 1,
|
updatedReplicas: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "updatedReplicas greater than replicas",
|
name: "updatedReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
updatedReplicas: 4,
|
updatedReplicas: 4,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid: number of available replicas",
|
name: "invalid: number of available replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
availableReplicas: int32(-1),
|
availableReplicas: int32(-1),
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid: available replicas greater than replicas",
|
name: "invalid: available replicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
currentReplicas: 2,
|
currentReplicas: 2,
|
||||||
availableReplicas: int32(4),
|
availableReplicas: int32(4),
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid: available replicas greater than ready replicas",
|
name: "invalid: available replicas greater than ready replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 2,
|
readyReplicas: 2,
|
||||||
@@ -842,23 +795,19 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||||||
errs field.ErrorList
|
errs field.ErrorList
|
||||||
}
|
}
|
||||||
|
|
||||||
successCases := []testCase{
|
successCases := []testCase{{
|
||||||
{
|
|
||||||
name: "update replica count",
|
name: "update replica count",
|
||||||
old: mkStatefulSet(&validPodTemplate),
|
old: mkStatefulSet(&validPodTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakReplicas(3)),
|
update: mkStatefulSet(&validPodTemplate, tweakReplicas(3)),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update containers 1",
|
name: "update containers 1",
|
||||||
old: mkStatefulSet(&validPodTemplate),
|
old: mkStatefulSet(&validPodTemplate),
|
||||||
update: mkStatefulSet(addContainersValidTemplate),
|
update: mkStatefulSet(addContainersValidTemplate),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update containers 2",
|
name: "update containers 2",
|
||||||
old: mkStatefulSet(addContainersValidTemplate),
|
old: mkStatefulSet(addContainersValidTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate),
|
update: mkStatefulSet(&validPodTemplate),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update containers and pvc retention policy 1",
|
name: "update containers and pvc retention policy 1",
|
||||||
old: mkStatefulSet(addContainersValidTemplate),
|
old: mkStatefulSet(addContainersValidTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate,
|
update: mkStatefulSet(&validPodTemplate,
|
||||||
@@ -867,8 +816,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||||||
tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType),
|
tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update containers and pvc retention policy 2",
|
name: "update containers and pvc retention policy 2",
|
||||||
old: mkStatefulSet(&validPodTemplate,
|
old: mkStatefulSet(&validPodTemplate,
|
||||||
tweakPVCPolicy(mkPVCPolicy(
|
tweakPVCPolicy(mkPVCPolicy(
|
||||||
@@ -876,54 +824,46 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
update: mkStatefulSet(&validPodTemplate),
|
update: mkStatefulSet(&validPodTemplate),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update update strategy",
|
name: "update update strategy",
|
||||||
old: mkStatefulSet(&validPodTemplate),
|
old: mkStatefulSet(&validPodTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate,
|
update: mkStatefulSet(&validPodTemplate,
|
||||||
tweakUpdateStrategyType(apps.OnDeleteStatefulSetStrategyType),
|
tweakUpdateStrategyType(apps.OnDeleteStatefulSetStrategyType),
|
||||||
),
|
),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update min ready seconds 1",
|
name: "update min ready seconds 1",
|
||||||
old: mkStatefulSet(&validPodTemplate),
|
old: mkStatefulSet(&validPodTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)),
|
update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update min ready seconds 2",
|
name: "update min ready seconds 2",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(5)),
|
old: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(5)),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)),
|
update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update existing instance with now-invalid name",
|
name: "update existing instance with now-invalid name",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakFinalizers("final")),
|
old: mkStatefulSet(&validPodTemplate, tweakFinalizers("final")),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakFinalizers()),
|
update: mkStatefulSet(&validPodTemplate, tweakFinalizers()),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update existing instance with .spec.ordinals.start",
|
name: "update existing instance with .spec.ordinals.start",
|
||||||
old: mkStatefulSet(&validPodTemplate),
|
old: mkStatefulSet(&validPodTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakOrdinalsStart(3)),
|
update: mkStatefulSet(&validPodTemplate, tweakOrdinalsStart(3)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := []testCase{
|
errorCases := []testCase{{
|
||||||
{
|
|
||||||
name: "update name",
|
name: "update name",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakName("abc")),
|
old: mkStatefulSet(&validPodTemplate, tweakName("abc")),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakName("abc2")),
|
update: mkStatefulSet(&validPodTemplate, tweakName("abc2")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), nil, ""),
|
field.Invalid(field.NewPath("metadata", "name"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update namespace",
|
name: "update namespace",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault)),
|
old: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault)),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault+"1")),
|
update: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault+"1")),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "namespace"), nil, ""),
|
field.Invalid(field.NewPath("metadata", "namespace"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update selector",
|
name: "update selector",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(validLabels)),
|
old: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(validLabels)),
|
||||||
update: mkStatefulSet(&validPodTemplate2,
|
update: mkStatefulSet(&validPodTemplate2,
|
||||||
@@ -932,48 +872,42 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
|
|||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Forbidden(field.NewPath("spec"), ""),
|
field.Forbidden(field.NewPath("spec"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update pod management policy 1",
|
name: "update pod management policy 1",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("")),
|
old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("")),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
|
update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Forbidden(field.NewPath("spec"), ""),
|
field.Forbidden(field.NewPath("spec"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update pod management policy 2",
|
name: "update pod management policy 2",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)),
|
old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
|
update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Forbidden(field.NewPath("spec"), ""),
|
field.Forbidden(field.NewPath("spec"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update to negative replicas",
|
name: "update to negative replicas",
|
||||||
old: mkStatefulSet(&validPodTemplate),
|
old: mkStatefulSet(&validPodTemplate),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)),
|
update: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "replicas"), nil, ""),
|
field.Invalid(field.NewPath("spec", "replicas"), nil, ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update pvc template size",
|
name: "update pvc template size",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
|
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedSize)),
|
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedSize)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Forbidden(field.NewPath("spec"), ""),
|
field.Forbidden(field.NewPath("spec"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "update pvc template storage class",
|
name: "update pvc template storage class",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
|
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedClass)),
|
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedClass)),
|
||||||
errs: field.ErrorList{
|
errs: field.ErrorList{
|
||||||
field.Forbidden(field.NewPath("spec"), ""),
|
field.Forbidden(field.NewPath("spec"), ""),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add new pvc template",
|
name: "add new pvc template",
|
||||||
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
|
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
|
||||||
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate, validPVCTemplate2)),
|
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate, validPVCTemplate2)),
|
||||||
@@ -1112,26 +1046,22 @@ func TestValidateControllerRevisionUpdate(t *testing.T) {
|
|||||||
newHistory apps.ControllerRevision
|
newHistory apps.ControllerRevision
|
||||||
oldHistory apps.ControllerRevision
|
oldHistory apps.ControllerRevision
|
||||||
isValid bool
|
isValid bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid",
|
name: "valid",
|
||||||
newHistory: valid,
|
newHistory: valid,
|
||||||
oldHistory: valid,
|
oldHistory: valid,
|
||||||
isValid: true,
|
isValid: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid",
|
name: "invalid",
|
||||||
newHistory: noVersion,
|
newHistory: noVersion,
|
||||||
oldHistory: valid,
|
oldHistory: valid,
|
||||||
isValid: false,
|
isValid: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "changed data",
|
name: "changed data",
|
||||||
newHistory: changedData,
|
newHistory: changedData,
|
||||||
oldHistory: valid,
|
oldHistory: valid,
|
||||||
isValid: false,
|
isValid: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "changed revision",
|
name: "changed revision",
|
||||||
newHistory: changedRevision,
|
newHistory: changedRevision,
|
||||||
oldHistory: valid,
|
oldHistory: valid,
|
||||||
@@ -1158,8 +1088,7 @@ func TestValidateDaemonSetStatusUpdate(t *testing.T) {
|
|||||||
update apps.DaemonSet
|
update apps.DaemonSet
|
||||||
}
|
}
|
||||||
|
|
||||||
successCases := []dsUpdateTest{
|
successCases := []dsUpdateTest{{
|
||||||
{
|
|
||||||
old: apps.DaemonSet{
|
old: apps.DaemonSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Status: apps.DaemonSetStatus{
|
Status: apps.DaemonSetStatus{
|
||||||
@@ -2071,8 +2000,7 @@ func TestValidateDaemonSet(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
successCases := []apps.DaemonSet{
|
successCases := []apps.DaemonSet{{
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.DaemonSetSpec{
|
Spec: apps.DaemonSetSpec{
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||||
@@ -2081,8 +2009,7 @@ func TestValidateDaemonSet(t *testing.T) {
|
|||||||
Type: apps.OnDeleteDaemonSetStrategyType,
|
Type: apps.OnDeleteDaemonSetStrategyType,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.DaemonSetSpec{
|
Spec: apps.DaemonSetSpec{
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
Selector: &metav1.LabelSelector{MatchLabels: validSelector},
|
||||||
@@ -2290,14 +2217,12 @@ func validDeployment() *apps.Deployment {
|
|||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
RestartPolicy: api.RestartPolicyAlways,
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
DNSPolicy: api.DNSDefault,
|
DNSPolicy: api.DNSDefault,
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{{
|
||||||
{
|
|
||||||
Name: "nginx",
|
Name: "nginx",
|
||||||
Image: "image",
|
Image: "image",
|
||||||
ImagePullPolicy: api.PullNever,
|
ImagePullPolicy: api.PullNever,
|
||||||
TerminationMessagePolicy: api.TerminationMessageReadFile,
|
TerminationMessagePolicy: api.TerminationMessageReadFile,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
RollbackTo: &apps.RollbackConfig{
|
RollbackTo: &apps.RollbackConfig{
|
||||||
@@ -2427,8 +2352,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
|
|||||||
collisionCount *int32
|
collisionCount *int32
|
||||||
|
|
||||||
expectedErr bool
|
expectedErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid status",
|
name: "valid status",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
updatedReplicas: 3,
|
updatedReplicas: 3,
|
||||||
@@ -2436,8 +2360,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: false,
|
expectedErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid replicas",
|
name: "invalid replicas",
|
||||||
replicas: -1,
|
replicas: -1,
|
||||||
updatedReplicas: 2,
|
updatedReplicas: 2,
|
||||||
@@ -2445,8 +2368,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid updatedReplicas",
|
name: "invalid updatedReplicas",
|
||||||
replicas: 2,
|
replicas: 2,
|
||||||
updatedReplicas: -1,
|
updatedReplicas: -1,
|
||||||
@@ -2454,32 +2376,28 @@ func TestValidateDeploymentStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid readyReplicas",
|
name: "invalid readyReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: -1,
|
readyReplicas: -1,
|
||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid availableReplicas",
|
name: "invalid availableReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
availableReplicas: -1,
|
availableReplicas: -1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid observedGeneration",
|
name: "invalid observedGeneration",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: -1,
|
observedGeneration: -1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "updatedReplicas greater than replicas",
|
name: "updatedReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
updatedReplicas: 4,
|
updatedReplicas: 4,
|
||||||
@@ -2487,32 +2405,28 @@ func TestValidateDeploymentStatus(t *testing.T) {
|
|||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "readyReplicas greater than replicas",
|
name: "readyReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 4,
|
readyReplicas: 4,
|
||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "availableReplicas greater than replicas",
|
name: "availableReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 3,
|
readyReplicas: 3,
|
||||||
availableReplicas: 4,
|
availableReplicas: 4,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "availableReplicas greater than readyReplicas",
|
name: "availableReplicas greater than readyReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
readyReplicas: 2,
|
readyReplicas: 2,
|
||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid collisionCount",
|
name: "invalid collisionCount",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
@@ -2548,8 +2462,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
|
|||||||
from, to apps.DeploymentStatus
|
from, to apps.DeploymentStatus
|
||||||
|
|
||||||
expectedErr bool
|
expectedErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "increase: valid update",
|
name: "increase: valid update",
|
||||||
from: apps.DeploymentStatus{
|
from: apps.DeploymentStatus{
|
||||||
CollisionCount: nil,
|
CollisionCount: nil,
|
||||||
@@ -2558,8 +2471,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
|
|||||||
CollisionCount: &collisionCount,
|
CollisionCount: &collisionCount,
|
||||||
},
|
},
|
||||||
expectedErr: false,
|
expectedErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "stable: valid update",
|
name: "stable: valid update",
|
||||||
from: apps.DeploymentStatus{
|
from: apps.DeploymentStatus{
|
||||||
CollisionCount: &collisionCount,
|
CollisionCount: &collisionCount,
|
||||||
@@ -2568,8 +2480,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
|
|||||||
CollisionCount: &collisionCount,
|
CollisionCount: &collisionCount,
|
||||||
},
|
},
|
||||||
expectedErr: false,
|
expectedErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "unset: invalid update",
|
name: "unset: invalid update",
|
||||||
from: apps.DeploymentStatus{
|
from: apps.DeploymentStatus{
|
||||||
CollisionCount: &collisionCount,
|
CollisionCount: &collisionCount,
|
||||||
@@ -2578,8 +2489,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
|
|||||||
CollisionCount: nil,
|
CollisionCount: nil,
|
||||||
},
|
},
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "decrease: invalid update",
|
name: "decrease: invalid update",
|
||||||
from: apps.DeploymentStatus{
|
from: apps.DeploymentStatus{
|
||||||
CollisionCount: &otherCollisionCount,
|
CollisionCount: &otherCollisionCount,
|
||||||
@@ -2872,8 +2782,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
observedGeneration int64
|
observedGeneration int64
|
||||||
|
|
||||||
expectedErr bool
|
expectedErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid status",
|
name: "valid status",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2881,8 +2790,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: false,
|
expectedErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid replicas",
|
name: "invalid replicas",
|
||||||
replicas: -1,
|
replicas: -1,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2890,8 +2798,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid fullyLabeledReplicas",
|
name: "invalid fullyLabeledReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: -1,
|
fullyLabeledReplicas: -1,
|
||||||
@@ -2899,8 +2806,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid readyReplicas",
|
name: "invalid readyReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2908,8 +2814,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 1,
|
availableReplicas: 1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid availableReplicas",
|
name: "invalid availableReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2917,8 +2822,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: -1,
|
availableReplicas: -1,
|
||||||
observedGeneration: 2,
|
observedGeneration: 2,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid observedGeneration",
|
name: "invalid observedGeneration",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2926,8 +2830,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: -1,
|
observedGeneration: -1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "fullyLabeledReplicas greater than replicas",
|
name: "fullyLabeledReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 4,
|
fullyLabeledReplicas: 4,
|
||||||
@@ -2935,8 +2838,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "readyReplicas greater than replicas",
|
name: "readyReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2944,8 +2846,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 3,
|
availableReplicas: 3,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "availableReplicas greater than replicas",
|
name: "availableReplicas greater than replicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2953,8 +2854,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
|
|||||||
availableReplicas: 4,
|
availableReplicas: 4,
|
||||||
observedGeneration: 1,
|
observedGeneration: 1,
|
||||||
expectedErr: true,
|
expectedErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "availableReplicas greater than readyReplicas",
|
name: "availableReplicas greater than readyReplicas",
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
fullyLabeledReplicas: 3,
|
fullyLabeledReplicas: 3,
|
||||||
@@ -2998,8 +2898,7 @@ func TestValidateReplicaSetStatusUpdate(t *testing.T) {
|
|||||||
old apps.ReplicaSet
|
old apps.ReplicaSet
|
||||||
update apps.ReplicaSet
|
update apps.ReplicaSet
|
||||||
}
|
}
|
||||||
successCases := []rcUpdateTest{
|
successCases := []rcUpdateTest{{
|
||||||
{
|
|
||||||
old: apps.ReplicaSet{
|
old: apps.ReplicaSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.ReplicaSetSpec{
|
Spec: apps.ReplicaSetSpec{
|
||||||
@@ -3300,22 +3199,19 @@ func TestValidateReplicaSet(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
successCases := []apps.ReplicaSet{
|
successCases := []apps.ReplicaSet{{
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.ReplicaSetSpec{
|
Spec: apps.ReplicaSetSpec{
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||||
Template: validPodTemplate.Template,
|
Template: validPodTemplate.Template,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.ReplicaSetSpec{
|
Spec: apps.ReplicaSetSpec{
|
||||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||||
Template: validPodTemplate.Template,
|
Template: validPodTemplate.Template,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.ReplicaSetSpec{
|
Spec: apps.ReplicaSetSpec{
|
||||||
Replicas: 1,
|
Replicas: 1,
|
||||||
|
@@ -40,13 +40,11 @@ func TestValidateSARSpec(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
obj authorizationapi.SubjectAccessReviewSpec
|
obj authorizationapi.SubjectAccessReviewSpec
|
||||||
msg string
|
msg string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "neither request",
|
name: "neither request",
|
||||||
obj: authorizationapi.SubjectAccessReviewSpec{User: "me"},
|
obj: authorizationapi.SubjectAccessReviewSpec{User: "me"},
|
||||||
msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
|
msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "both requests",
|
name: "both requests",
|
||||||
obj: authorizationapi.SubjectAccessReviewSpec{
|
obj: authorizationapi.SubjectAccessReviewSpec{
|
||||||
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
||||||
@@ -54,15 +52,13 @@ func TestValidateSARSpec(t *testing.T) {
|
|||||||
User: "me",
|
User: "me",
|
||||||
},
|
},
|
||||||
msg: "cannot be specified in combination with resourceAttributes",
|
msg: "cannot be specified in combination with resourceAttributes",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "no subject",
|
name: "no subject",
|
||||||
obj: authorizationapi.SubjectAccessReviewSpec{
|
obj: authorizationapi.SubjectAccessReviewSpec{
|
||||||
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
||||||
},
|
},
|
||||||
msg: `spec.user: Invalid value: "": at least one of user or group must be specified`,
|
msg: `spec.user: Invalid value: "": at least one of user or group must be specified`,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range errorCases {
|
for _, c := range errorCases {
|
||||||
errs := ValidateSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
|
errs := ValidateSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
|
||||||
@@ -102,21 +98,18 @@ func TestValidateSelfSAR(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
obj authorizationapi.SelfSubjectAccessReviewSpec
|
obj authorizationapi.SelfSubjectAccessReviewSpec
|
||||||
msg string
|
msg string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "neither request",
|
name: "neither request",
|
||||||
obj: authorizationapi.SelfSubjectAccessReviewSpec{},
|
obj: authorizationapi.SelfSubjectAccessReviewSpec{},
|
||||||
msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
|
msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "both requests",
|
name: "both requests",
|
||||||
obj: authorizationapi.SelfSubjectAccessReviewSpec{
|
obj: authorizationapi.SelfSubjectAccessReviewSpec{
|
||||||
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
||||||
NonResourceAttributes: &authorizationapi.NonResourceAttributes{},
|
NonResourceAttributes: &authorizationapi.NonResourceAttributes{},
|
||||||
},
|
},
|
||||||
msg: "cannot be specified in combination with resourceAttributes",
|
msg: "cannot be specified in combination with resourceAttributes",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range errorCases {
|
for _, c := range errorCases {
|
||||||
errs := ValidateSelfSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
|
errs := ValidateSelfSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
|
||||||
@@ -136,14 +129,12 @@ func TestValidateSelfSAR(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateLocalSAR(t *testing.T) {
|
func TestValidateLocalSAR(t *testing.T) {
|
||||||
successCases := []authorizationapi.LocalSubjectAccessReview{
|
successCases := []authorizationapi.LocalSubjectAccessReview{{
|
||||||
{
|
|
||||||
Spec: authorizationapi.SubjectAccessReviewSpec{
|
Spec: authorizationapi.SubjectAccessReviewSpec{
|
||||||
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
ResourceAttributes: &authorizationapi.ResourceAttributes{},
|
||||||
User: "user",
|
User: "user",
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, successCase := range successCases {
|
for _, successCase := range successCases {
|
||||||
if errs := ValidateLocalSubjectAccessReview(&successCase); len(errs) != 0 {
|
if errs := ValidateLocalSubjectAccessReview(&successCase); len(errs) != 0 {
|
||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
@@ -154,8 +145,7 @@ func TestValidateLocalSAR(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
obj *authorizationapi.LocalSubjectAccessReview
|
obj *authorizationapi.LocalSubjectAccessReview
|
||||||
msg string
|
msg string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "name",
|
name: "name",
|
||||||
obj: &authorizationapi.LocalSubjectAccessReview{
|
obj: &authorizationapi.LocalSubjectAccessReview{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "a"},
|
ObjectMeta: metav1.ObjectMeta{Name: "a"},
|
||||||
@@ -165,8 +155,7 @@ func TestValidateLocalSAR(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
msg: "must be empty except for namespace",
|
msg: "must be empty except for namespace",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "namespace conflict",
|
name: "namespace conflict",
|
||||||
obj: &authorizationapi.LocalSubjectAccessReview{
|
obj: &authorizationapi.LocalSubjectAccessReview{
|
||||||
ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
|
ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
|
||||||
@@ -176,8 +165,7 @@ func TestValidateLocalSAR(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
msg: "must match metadata.namespace",
|
msg: "must match metadata.namespace",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "nonresource",
|
name: "nonresource",
|
||||||
obj: &authorizationapi.LocalSubjectAccessReview{
|
obj: &authorizationapi.LocalSubjectAccessReview{
|
||||||
ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
|
ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
|
||||||
@@ -187,8 +175,7 @@ func TestValidateLocalSAR(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
msg: "disallowed on this kind of request",
|
msg: "disallowed on this kind of request",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range errorCases {
|
for _, c := range errorCases {
|
||||||
errs := ValidateLocalSubjectAccessReview(c.obj)
|
errs := ValidateLocalSubjectAccessReview(c.obj)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -112,49 +112,39 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.PodConditionType("CustomConditionType"),
|
Type: api.PodConditionType("CustomConditionType"),
|
||||||
Status: api.ConditionFalse,
|
Status: api.ConditionFalse,
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionCount,
|
Action: batch.PodFailurePolicyActionCount,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
ContainerName: pointer.String("abc"),
|
ContainerName: pointer.String("abc"),
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
ContainerName: pointer.String("def"),
|
ContainerName: pointer.String("def"),
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{4},
|
Values: []int32{4},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpNotIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpNotIn,
|
||||||
Values: []int32{5, 6, 7},
|
Values: []int32{5, 6, 7},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -314,11 +304,9 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -331,15 +319,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{11, 11},
|
Values: []int32{11, 11},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -352,8 +338,7 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
@@ -365,8 +350,7 @@ func TestValidateJob(t *testing.T) {
|
|||||||
return tooManyValues
|
return tooManyValues
|
||||||
}(),
|
}(),
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -404,8 +388,7 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnPodConditions: func() []batch.PodFailurePolicyOnPodConditionsPattern {
|
OnPodConditions: func() []batch.PodFailurePolicyOnPodConditionsPattern {
|
||||||
tooManyPatterns := make([]batch.PodFailurePolicyOnPodConditionsPattern, maxPodFailurePolicyOnPodConditionsPatterns+1)
|
tooManyPatterns := make([]batch.PodFailurePolicyOnPodConditionsPattern, maxPodFailurePolicyOnPodConditionsPatterns+1)
|
||||||
@@ -417,8 +400,7 @@ func TestValidateJob(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return tooManyPatterns
|
return tooManyPatterns
|
||||||
}(),
|
}(),
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -431,15 +413,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{12, 13, 13, 13},
|
Values: []int32{12, 13, 13, 13},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -452,15 +432,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{19, 11},
|
Values: []int32{19, 11},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -473,15 +451,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{},
|
Values: []int32{},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -494,15 +470,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: "",
|
Action: "",
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -515,15 +489,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: "",
|
Operator: "",
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -536,22 +508,18 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
ContainerName: pointer.String("abc"),
|
ContainerName: pointer.String("abc"),
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -564,15 +532,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{1, 0, 2},
|
Values: []int32{1, 0, 2},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -585,24 +551,21 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
ContainerName: pointer.String("abc"),
|
ContainerName: pointer.String("abc"),
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionFailJob,
|
Action: batch.PodFailurePolicyActionFailJob,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
ContainerName: pointer.String("xyz"),
|
ContainerName: pointer.String("xyz"),
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{5, 6, 7},
|
Values: []int32{5, 6, 7},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -615,16 +578,14 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: "UnknownAction",
|
Action: "UnknownAction",
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
ContainerName: pointer.String("abc"),
|
ContainerName: pointer.String("abc"),
|
||||||
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
Operator: batch.PodFailurePolicyOnExitCodesOpIn,
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -637,15 +598,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
|
||||||
Operator: "UnknownOperator",
|
Operator: "UnknownOperator",
|
||||||
Values: []int32{1, 2, 3},
|
Values: []int32{1, 2, 3},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -658,16 +617,12 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -680,17 +635,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: "UnknownStatus",
|
Status: "UnknownStatus",
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -703,16 +654,12 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -725,17 +672,13 @@ func TestValidateJob(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.PodConditionType("Invalid Condition Type"),
|
Type: api.PodConditionType("Invalid Condition Type"),
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1116,17 +1059,13 @@ func TestValidateJobUpdate(t *testing.T) {
|
|||||||
validNodeAffinity := &api.Affinity{
|
validNodeAffinity := &api.Affinity{
|
||||||
NodeAffinity: &api.NodeAffinity{
|
NodeAffinity: &api.NodeAffinity{
|
||||||
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
|
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
|
||||||
NodeSelectorTerms: []api.NodeSelectorTerm{
|
NodeSelectorTerms: []api.NodeSelectorTerm{{
|
||||||
{
|
MatchExpressions: []api.NodeSelectorRequirement{{
|
||||||
MatchExpressions: []api.NodeSelectorRequirement{
|
|
||||||
{
|
|
||||||
Key: "foo",
|
Key: "foo",
|
||||||
Operator: api.NodeSelectorOpIn,
|
Operator: api.NodeSelectorOpIn,
|
||||||
Values: []string{"bar", "value2"},
|
Values: []string{"bar", "value2"},
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1134,17 +1073,13 @@ func TestValidateJobUpdate(t *testing.T) {
|
|||||||
validPodTemplateWithAffinity.Spec.Affinity = &api.Affinity{
|
validPodTemplateWithAffinity.Spec.Affinity = &api.Affinity{
|
||||||
NodeAffinity: &api.NodeAffinity{
|
NodeAffinity: &api.NodeAffinity{
|
||||||
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
|
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
|
||||||
NodeSelectorTerms: []api.NodeSelectorTerm{
|
NodeSelectorTerms: []api.NodeSelectorTerm{{
|
||||||
{
|
MatchExpressions: []api.NodeSelectorRequirement{{
|
||||||
MatchExpressions: []api.NodeSelectorRequirement{
|
|
||||||
{
|
|
||||||
Key: "foo",
|
Key: "foo",
|
||||||
Operator: api.NodeSelectorOpIn,
|
Operator: api.NodeSelectorOpIn,
|
||||||
Values: []string{"bar", "value"},
|
Values: []string{"bar", "value"},
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1242,17 +1177,13 @@ func TestValidateJobUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
update: func(job *batch.Job) {
|
update: func(job *batch.Job) {
|
||||||
job.Spec.PodFailurePolicy = &batch.PodFailurePolicy{
|
job.Spec.PodFailurePolicy = &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
err: &field.Error{
|
err: &field.Error{
|
||||||
@@ -1267,29 +1198,23 @@ func TestValidateJobUpdate(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update: func(job *batch.Job) {
|
update: func(job *batch.Job) {
|
||||||
job.Spec.PodFailurePolicy.Rules = append(job.Spec.PodFailurePolicy.Rules, batch.PodFailurePolicyRule{
|
job.Spec.PodFailurePolicy.Rules = append(job.Spec.PodFailurePolicy.Rules, batch.PodFailurePolicyRule{
|
||||||
Action: batch.PodFailurePolicyActionCount,
|
Action: batch.PodFailurePolicyActionCount,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
err: &field.Error{
|
err: &field.Error{
|
||||||
@@ -1304,17 +1229,13 @@ func TestValidateJobUpdate(t *testing.T) {
|
|||||||
Selector: validGeneratedSelector,
|
Selector: validGeneratedSelector,
|
||||||
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
|
||||||
PodFailurePolicy: &batch.PodFailurePolicy{
|
PodFailurePolicy: &batch.PodFailurePolicy{
|
||||||
Rules: []batch.PodFailurePolicyRule{
|
Rules: []batch.PodFailurePolicyRule{{
|
||||||
{
|
|
||||||
Action: batch.PodFailurePolicyActionIgnore,
|
Action: batch.PodFailurePolicyActionIgnore,
|
||||||
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{
|
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
|
||||||
{
|
|
||||||
Type: api.DisruptionTarget,
|
Type: api.DisruptionTarget,
|
||||||
Status: api.ConditionTrue,
|
Status: api.ConditionTrue,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -413,18 +413,15 @@ func Test_getValidationOptions(t *testing.T) {
|
|||||||
newCSR *capi.CertificateSigningRequest
|
newCSR *capi.CertificateSigningRequest
|
||||||
oldCSR *capi.CertificateSigningRequest
|
oldCSR *capi.CertificateSigningRequest
|
||||||
want certificateValidationOptions
|
want certificateValidationOptions
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "strict create",
|
name: "strict create",
|
||||||
oldCSR: nil,
|
oldCSR: nil,
|
||||||
want: certificateValidationOptions{},
|
want: certificateValidationOptions{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "strict update",
|
name: "strict update",
|
||||||
oldCSR: &capi.CertificateSigningRequest{},
|
oldCSR: &capi.CertificateSigningRequest{},
|
||||||
want: certificateValidationOptions{},
|
want: certificateValidationOptions{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, approved+denied",
|
name: "compatible update, approved+denied",
|
||||||
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateDenied}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateDenied}},
|
||||||
@@ -432,15 +429,13 @@ func Test_getValidationOptions(t *testing.T) {
|
|||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowBothApprovedAndDenied: true,
|
allowBothApprovedAndDenied: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, legacy signerName",
|
name: "compatible update, legacy signerName",
|
||||||
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{SignerName: capi.LegacyUnknownSignerName}},
|
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{SignerName: capi.LegacyUnknownSignerName}},
|
||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowLegacySignerName: true,
|
allowLegacySignerName: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, duplicate condition types",
|
name: "compatible update, duplicate condition types",
|
||||||
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateApproved}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateApproved}},
|
||||||
@@ -448,8 +443,7 @@ func Test_getValidationOptions(t *testing.T) {
|
|||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowDuplicateConditionTypes: true,
|
allowDuplicateConditionTypes: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, empty condition types",
|
name: "compatible update, empty condition types",
|
||||||
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{}},
|
Conditions: []capi.CertificateSigningRequestCondition{{}},
|
||||||
@@ -457,8 +451,7 @@ func Test_getValidationOptions(t *testing.T) {
|
|||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowEmptyConditionType: true,
|
allowEmptyConditionType: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, no diff to certificate",
|
name: "compatible update, no diff to certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: validCertificate,
|
Certificate: validCertificate,
|
||||||
@@ -469,8 +462,7 @@ func Test_getValidationOptions(t *testing.T) {
|
|||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowArbitraryCertificate: true,
|
allowArbitraryCertificate: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, existing invalid certificate",
|
name: "compatible update, existing invalid certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: []byte(`new - no PEM blocks`),
|
Certificate: []byte(`new - no PEM blocks`),
|
||||||
@@ -481,22 +473,19 @@ func Test_getValidationOptions(t *testing.T) {
|
|||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowArbitraryCertificate: true,
|
allowArbitraryCertificate: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, existing unknown usages",
|
name: "compatible update, existing unknown usages",
|
||||||
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"unknown"}}},
|
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"unknown"}}},
|
||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowUnknownUsages: true,
|
allowUnknownUsages: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "compatible update, existing duplicate usages",
|
name: "compatible update, existing duplicate usages",
|
||||||
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"any", "any"}}},
|
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"any", "any"}}},
|
||||||
want: certificateValidationOptions{
|
want: certificateValidationOptions{
|
||||||
allowDuplicateUsages: true,
|
allowDuplicateUsages: true,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if got := getValidationOptions(tt.newCSR, tt.oldCSR); !reflect.DeepEqual(got, tt.want) {
|
if got := getValidationOptions(tt.newCSR, tt.oldCSR); !reflect.DeepEqual(got, tt.want) {
|
||||||
@@ -524,18 +513,15 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
newCSR *capi.CertificateSigningRequest
|
newCSR *capi.CertificateSigningRequest
|
||||||
oldCSR *capi.CertificateSigningRequest
|
oldCSR *capi.CertificateSigningRequest
|
||||||
errs []string
|
errs []string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "no-op",
|
name: "no-op",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "finalizer change with invalid status",
|
name: "finalizer change with invalid status",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Approved condition",
|
name: "add Approved condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
||||||
@@ -544,8 +530,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not add a condition of type "Approved"`,
|
`status.conditions: Forbidden: updates may not add a condition of type "Approved"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Approved condition",
|
name: "remove Approved condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -554,8 +539,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Denied condition",
|
name: "add Denied condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
||||||
@@ -564,8 +548,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not add a condition of type "Denied"`,
|
`status.conditions: Forbidden: updates may not add a condition of type "Denied"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Denied condition",
|
name: "remove Denied condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -574,16 +557,14 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Failed condition",
|
name: "add Failed condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
||||||
}},
|
}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
||||||
errs: []string{},
|
errs: []string{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Failed condition",
|
name: "remove Failed condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -592,8 +573,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "set certificate",
|
name: "set certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: validCertificate,
|
Certificate: validCertificate,
|
||||||
@@ -602,8 +582,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.certificate: Forbidden: updates may not set certificate content`,
|
`status.certificate: Forbidden: updates may not set certificate content`,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@@ -640,18 +619,15 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
newCSR *capi.CertificateSigningRequest
|
newCSR *capi.CertificateSigningRequest
|
||||||
oldCSR *capi.CertificateSigningRequest
|
oldCSR *capi.CertificateSigningRequest
|
||||||
errs []string
|
errs []string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "no-op",
|
name: "no-op",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "finalizer change with invalid status",
|
name: "finalizer change with invalid status",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "finalizer change with duplicate and unknown usages",
|
name: "finalizer change with duplicate and unknown usages",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: capi.CertificateSigningRequestSpec{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: capi.CertificateSigningRequestSpec{
|
||||||
Usages: []capi.KeyUsage{"unknown", "unknown"},
|
Usages: []capi.KeyUsage{"unknown", "unknown"},
|
||||||
@@ -663,8 +639,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
Request: newCSRPEM(t),
|
Request: newCSRPEM(t),
|
||||||
SignerName: validSignerName,
|
SignerName: validSignerName,
|
||||||
}},
|
}},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Approved condition",
|
name: "add Approved condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
||||||
@@ -673,8 +648,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not add a condition of type "Approved"`,
|
`status.conditions: Forbidden: updates may not add a condition of type "Approved"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Approved condition",
|
name: "remove Approved condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -683,8 +657,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Denied condition",
|
name: "add Denied condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
||||||
@@ -693,8 +666,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not add a condition of type "Denied"`,
|
`status.conditions: Forbidden: updates may not add a condition of type "Denied"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Denied condition",
|
name: "remove Denied condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -703,16 +675,14 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Failed condition",
|
name: "add Failed condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
||||||
}},
|
}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
||||||
errs: []string{},
|
errs: []string{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Failed condition",
|
name: "remove Failed condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -721,16 +691,14 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "set valid certificate",
|
name: "set valid certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: validCertificate,
|
Certificate: validCertificate,
|
||||||
}},
|
}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
||||||
errs: []string{},
|
errs: []string{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "set invalid certificate",
|
name: "set invalid certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: invalidCertificateNoPEM,
|
Certificate: invalidCertificateNoPEM,
|
||||||
@@ -739,8 +707,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`,
|
`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "reset certificate",
|
name: "reset certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: invalidCertificateNonCertificatePEM,
|
Certificate: invalidCertificateNonCertificatePEM,
|
||||||
@@ -751,8 +718,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.certificate: Forbidden: updates may not modify existing certificate content`,
|
`status.certificate: Forbidden: updates may not modify existing certificate content`,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@@ -789,25 +755,21 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
|
|||||||
newCSR *capi.CertificateSigningRequest
|
newCSR *capi.CertificateSigningRequest
|
||||||
oldCSR *capi.CertificateSigningRequest
|
oldCSR *capi.CertificateSigningRequest
|
||||||
errs []string
|
errs []string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "no-op",
|
name: "no-op",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "finalizer change with invalid certificate",
|
name: "finalizer change with invalid certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Approved condition",
|
name: "add Approved condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
||||||
}},
|
}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Approved condition",
|
name: "remove Approved condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -816,15 +778,13 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Denied condition",
|
name: "add Denied condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
||||||
}},
|
}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Denied condition",
|
name: "remove Denied condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -833,16 +793,14 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "add Failed condition",
|
name: "add Failed condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
||||||
}},
|
}},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
|
||||||
errs: []string{},
|
errs: []string{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "remove Failed condition",
|
name: "remove Failed condition",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
|
||||||
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -851,8 +809,7 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
|
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "set certificate",
|
name: "set certificate",
|
||||||
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
|
||||||
Certificate: validCertificate,
|
Certificate: validCertificate,
|
||||||
@@ -861,8 +818,7 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
|
|||||||
errs: []string{
|
errs: []string{
|
||||||
`status.certificate: Forbidden: updates may not set certificate content`,
|
`status.certificate: Forbidden: updates may not set certificate content`,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@@ -909,32 +865,28 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no status",
|
name: "no status",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec},
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "approved condition",
|
name: "approved condition",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "denied condition",
|
name: "denied condition",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "failed condition",
|
name: "failed condition",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "approved+issued",
|
name: "approved+issued",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -969,8 +921,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowEmptyConditionType: true},
|
lenientOpts: certificateValidationOptions{allowEmptyConditionType: true},
|
||||||
strictErrs: []string{`status.conditions[0].type: Required value`},
|
strictErrs: []string{`status.conditions[0].type: Required value`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "approved and denied",
|
name: "approved and denied",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -979,8 +930,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowBothApprovedAndDenied: true},
|
lenientOpts: certificateValidationOptions{allowBothApprovedAndDenied: true},
|
||||||
strictErrs: []string{`status.conditions[1].type: Invalid value: "Denied": Approved and Denied conditions are mutually exclusive`},
|
strictErrs: []string{`status.conditions[1].type: Invalid value: "Denied": Approved and Denied conditions are mutually exclusive`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "duplicate condition",
|
name: "duplicate condition",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -1002,8 +952,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
||||||
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`},
|
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "status.certificate, non-CERTIFICATE PEM",
|
name: "status.certificate, non-CERTIFICATE PEM",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -1013,8 +962,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
||||||
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": only CERTIFICATE PEM blocks are allowed, found "CERTIFICATE1"`},
|
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": only CERTIFICATE PEM blocks are allowed, found "CERTIFICATE1"`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "status.certificate, PEM headers",
|
name: "status.certificate, PEM headers",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -1024,8 +972,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
||||||
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": no PEM block headers are permitted`},
|
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": no PEM block headers are permitted`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "status.certificate, non-base64 PEM",
|
name: "status.certificate, non-base64 PEM",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -1035,8 +982,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
||||||
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`},
|
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "status.certificate, empty PEM block",
|
name: "status.certificate, empty PEM block",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -1046,8 +992,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
|
||||||
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": found CERTIFICATE PEM block containing 0 certificates`},
|
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": found CERTIFICATE PEM block containing 0 certificates`},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "status.certificate, non-ASN1 data",
|
name: "status.certificate, non-ASN1 data",
|
||||||
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
|
||||||
Status: capi.CertificateSigningRequestStatus{
|
Status: capi.CertificateSigningRequestStatus{
|
||||||
@@ -1164,8 +1109,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
bundle *capi.ClusterTrustBundle
|
bundle *capi.ClusterTrustBundle
|
||||||
opts ValidateClusterTrustBundleOptions
|
opts ValidateClusterTrustBundleOptions
|
||||||
wantErrors field.ErrorList
|
wantErrors field.ErrorList
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
description: "valid, no signer name",
|
description: "valid, no signer name",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1175,8 +1119,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
TrustBundle: goodCert1Block,
|
TrustBundle: goodCert1Block,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, no signer name, invalid name",
|
description: "invalid, no signer name, invalid name",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1189,8 +1132,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:bar:foo", "ClusterTrustBundle without signer name must not have \":\" in its name"),
|
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:bar:foo", "ClusterTrustBundle without signer name must not have \":\" in its name"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "valid, with signer name",
|
description: "valid, with signer name",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1201,8 +1143,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
TrustBundle: goodCert1Block,
|
TrustBundle: goodCert1Block,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, with signer name, missing name prefix",
|
description: "invalid, with signer name, missing name prefix",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1216,8 +1157,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), "look-ma-no-prefix", "ClusterTrustBundle for signerName k8s.io/foo must be named with prefix k8s.io:foo:"),
|
field.Invalid(field.NewPath("metadata", "name"), "look-ma-no-prefix", "ClusterTrustBundle for signerName k8s.io/foo must be named with prefix k8s.io:foo:"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, with signer name, empty name suffix",
|
description: "invalid, with signer name, empty name suffix",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1231,8 +1171,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`),
|
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, with signer name, bad name suffix",
|
description: "invalid, with signer name, bad name suffix",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1246,8 +1185,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:123notvalidDNSSubdomain", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`),
|
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:123notvalidDNSSubdomain", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "valid, with signer name, with inter-block garbage",
|
description: "valid, with signer name, with inter-block garbage",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1258,8 +1196,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
TrustBundle: "garbage\n" + goodCert1Block + "\ngarbage\n" + goodCert2Block,
|
TrustBundle: "garbage\n" + goodCert1Block + "\ngarbage\n" + goodCert2Block,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, no signer name, no trust anchors",
|
description: "invalid, no signer name, no trust anchors",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1270,8 +1207,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, no trust anchors",
|
description: "invalid, no trust anchors",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1284,8 +1220,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, bad signer name",
|
description: "invalid, bad signer name",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1299,8 +1234,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "signerName"), "invalid", "must be a fully qualified domain and path of the form 'example.com/signer-name'"),
|
field.Invalid(field.NewPath("spec", "signerName"), "invalid", "must be a fully qualified domain and path of the form 'example.com/signer-name'"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, no blocks",
|
description: "invalid, no blocks",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1313,8 +1247,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, bad block type",
|
description: "invalid, bad block type",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1327,8 +1260,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has bad block type: NOTACERTIFICATE"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has bad block type: NOTACERTIFICATE"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, block with headers",
|
description: "invalid, block with headers",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1341,8 +1273,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has PEM block headers"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has PEM block headers"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, cert is not a CA cert",
|
description: "invalid, cert is not a CA cert",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1355,8 +1286,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 0 does not have the CA bit set"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 0 does not have the CA bit set"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, duplicated blocks",
|
description: "invalid, duplicated blocks",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1369,8 +1299,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "duplicate trust anchor (indices [0 1])"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "duplicate trust anchor (indices [0 1])"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "invalid, non-certificate entry",
|
description: "invalid, non-certificate entry",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1383,8 +1312,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 does not parse as X.509"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 does not parse as X.509"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "allow any old garbage in the PEM field if we suppress parsing",
|
description: "allow any old garbage in the PEM field if we suppress parsing",
|
||||||
bundle: &capi.ClusterTrustBundle{
|
bundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1397,8 +1325,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
|
|||||||
opts: ValidateClusterTrustBundleOptions{
|
opts: ValidateClusterTrustBundleOptions{
|
||||||
SuppressBundleParsing: true,
|
SuppressBundleParsing: true,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
gotErrors := ValidateClusterTrustBundle(tc.bundle, tc.opts)
|
gotErrors := ValidateClusterTrustBundle(tc.bundle, tc.opts)
|
||||||
@@ -1454,8 +1381,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
|
|||||||
description string
|
description string
|
||||||
oldBundle, newBundle *capi.ClusterTrustBundle
|
oldBundle, newBundle *capi.ClusterTrustBundle
|
||||||
wantErrors field.ErrorList
|
wantErrors field.ErrorList
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
description: "changing signer name disallowed",
|
description: "changing signer name disallowed",
|
||||||
oldBundle: &capi.ClusterTrustBundle{
|
oldBundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1479,8 +1405,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
|
|||||||
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:bar", "ClusterTrustBundle for signerName k8s.io/bar must be named with prefix k8s.io:bar:"),
|
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:bar", "ClusterTrustBundle for signerName k8s.io/bar must be named with prefix k8s.io:bar:"),
|
||||||
field.Invalid(field.NewPath("spec", "signerName"), "k8s.io/bar", "field is immutable"),
|
field.Invalid(field.NewPath("spec", "signerName"), "k8s.io/bar", "field is immutable"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "adding certificate allowed",
|
description: "adding certificate allowed",
|
||||||
oldBundle: &capi.ClusterTrustBundle{
|
oldBundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1500,8 +1425,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
|
|||||||
TrustBundle: goodCert1Block + "\n" + goodCert2Block,
|
TrustBundle: goodCert1Block + "\n" + goodCert2Block,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "emptying trustBundle disallowed",
|
description: "emptying trustBundle disallowed",
|
||||||
oldBundle: &capi.ClusterTrustBundle{
|
oldBundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1524,8 +1448,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "emptying trustBundle (replace with non-block garbage) disallowed",
|
description: "emptying trustBundle (replace with non-block garbage) disallowed",
|
||||||
oldBundle: &capi.ClusterTrustBundle{
|
oldBundle: &capi.ClusterTrustBundle{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -1548,8 +1471,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
|
|||||||
wantErrors: field.ErrorList{
|
wantErrors: field.ErrorList{
|
||||||
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
@@ -31,8 +31,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
successCase := []struct {
|
successCase := []struct {
|
||||||
name string
|
name string
|
||||||
requirements v1.ResourceRequirements
|
requirements v1.ResourceRequirements
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Resources with Requests equal to Limits",
|
name: "Resources with Requests equal to Limits",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Requests: v1.ResourceList{
|
Requests: v1.ResourceList{
|
||||||
@@ -44,8 +43,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
|
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Resources with only Limits",
|
name: "Resources with only Limits",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Limits: v1.ResourceList{
|
Limits: v1.ResourceList{
|
||||||
@@ -54,8 +52,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
v1.ResourceName("my.org/resource"): resource.MustParse("10"),
|
v1.ResourceName("my.org/resource"): resource.MustParse("10"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Resources with only Requests",
|
name: "Resources with only Requests",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Requests: v1.ResourceList{
|
Requests: v1.ResourceList{
|
||||||
@@ -64,8 +61,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
v1.ResourceName("my.org/resource"): resource.MustParse("10"),
|
v1.ResourceName("my.org/resource"): resource.MustParse("10"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Resources with Requests Less Than Limits",
|
name: "Resources with Requests Less Than Limits",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Requests: v1.ResourceList{
|
Requests: v1.ResourceList{
|
||||||
@@ -79,8 +75,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
v1.ResourceName("my.org/resource"): resource.MustParse("9"),
|
v1.ResourceName("my.org/resource"): resource.MustParse("9"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range successCase {
|
for _, tc := range successCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources")); len(errs) != 0 {
|
if errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources")); len(errs) != 0 {
|
||||||
@@ -94,8 +89,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
requirements v1.ResourceRequirements
|
requirements v1.ResourceRequirements
|
||||||
skipLimitValueCheck bool
|
skipLimitValueCheck bool
|
||||||
skipRequestValueCheck bool
|
skipRequestValueCheck bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Resources with Requests Larger Than Limits",
|
name: "Resources with Requests Larger Than Limits",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Requests: v1.ResourceList{
|
Requests: v1.ResourceList{
|
||||||
@@ -109,8 +103,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
v1.ResourceName("my.org/resource"): resource.MustParse("9m"),
|
v1.ResourceName("my.org/resource"): resource.MustParse("9m"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Invalid Resources with Requests",
|
name: "Invalid Resources with Requests",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Requests: v1.ResourceList{
|
Requests: v1.ResourceList{
|
||||||
@@ -118,8 +111,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
skipRequestValueCheck: true,
|
skipRequestValueCheck: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Invalid Resources with Limits",
|
name: "Invalid Resources with Limits",
|
||||||
requirements: v1.ResourceRequirements{
|
requirements: v1.ResourceRequirements{
|
||||||
Limits: v1.ResourceList{
|
Limits: v1.ResourceList{
|
||||||
@@ -127,8 +119,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
skipLimitValueCheck: true,
|
skipLimitValueCheck: true,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range errorCase {
|
for _, tc := range errorCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources"))
|
errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources"))
|
||||||
@@ -168,28 +159,22 @@ func TestValidateContainerResourceName(t *testing.T) {
|
|||||||
successCase := []struct {
|
successCase := []struct {
|
||||||
name string
|
name string
|
||||||
ResourceName string
|
ResourceName string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "CPU resource",
|
name: "CPU resource",
|
||||||
ResourceName: "cpu",
|
ResourceName: "cpu",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Memory resource",
|
name: "Memory resource",
|
||||||
ResourceName: "memory",
|
ResourceName: "memory",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Hugepages resource",
|
name: "Hugepages resource",
|
||||||
ResourceName: "hugepages-2Mi",
|
ResourceName: "hugepages-2Mi",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Namespaced resource",
|
name: "Namespaced resource",
|
||||||
ResourceName: "kubernetes.io/resource-foo",
|
ResourceName: "kubernetes.io/resource-foo",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Extended Resource",
|
name: "Extended Resource",
|
||||||
ResourceName: "my.org/resource-bar",
|
ResourceName: "my.org/resource-bar",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range successCase {
|
for _, tc := range successCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) != 0 {
|
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) != 0 {
|
||||||
@@ -201,20 +186,16 @@ func TestValidateContainerResourceName(t *testing.T) {
|
|||||||
errorCase := []struct {
|
errorCase := []struct {
|
||||||
name string
|
name string
|
||||||
ResourceName string
|
ResourceName string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Invalid standard resource",
|
name: "Invalid standard resource",
|
||||||
ResourceName: "cpu-core",
|
ResourceName: "cpu-core",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Invalid namespaced resource",
|
name: "Invalid namespaced resource",
|
||||||
ResourceName: "kubernetes.io/",
|
ResourceName: "kubernetes.io/",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Invalid extended resource",
|
name: "Invalid extended resource",
|
||||||
ResourceName: "my.org-foo-resource",
|
ResourceName: "my.org-foo-resource",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range errorCase {
|
for _, tc := range errorCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) == 0 {
|
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) == 0 {
|
||||||
@@ -239,45 +220,38 @@ func TestValidatePodLogOptions(t *testing.T) {
|
|||||||
successCase := []struct {
|
successCase := []struct {
|
||||||
name string
|
name string
|
||||||
podLogOptions v1.PodLogOptions
|
podLogOptions v1.PodLogOptions
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Empty PodLogOptions",
|
name: "Empty PodLogOptions",
|
||||||
podLogOptions: v1.PodLogOptions{},
|
podLogOptions: v1.PodLogOptions{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "PodLogOptions with TailLines",
|
name: "PodLogOptions with TailLines",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
TailLines: &positiveLine,
|
TailLines: &positiveLine,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "PodLogOptions with LimitBytes",
|
name: "PodLogOptions with LimitBytes",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
LimitBytes: &limitBytesGreaterThan1,
|
LimitBytes: &limitBytesGreaterThan1,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "PodLogOptions with only sinceSeconds",
|
name: "PodLogOptions with only sinceSeconds",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
SinceSeconds: &sinceSecondsGreaterThan1,
|
SinceSeconds: &sinceSecondsGreaterThan1,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "PodLogOptions with LimitBytes with TailLines",
|
name: "PodLogOptions with LimitBytes with TailLines",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
LimitBytes: &limitBytesGreaterThan1,
|
LimitBytes: &limitBytesGreaterThan1,
|
||||||
TailLines: &positiveLine,
|
TailLines: &positiveLine,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "PodLogOptions with LimitBytes with TailLines with SinceSeconds",
|
name: "PodLogOptions with LimitBytes with TailLines with SinceSeconds",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
LimitBytes: &limitBytesGreaterThan1,
|
LimitBytes: &limitBytesGreaterThan1,
|
||||||
TailLines: &positiveLine,
|
TailLines: &positiveLine,
|
||||||
SinceSeconds: &sinceSecondsGreaterThan1,
|
SinceSeconds: &sinceSecondsGreaterThan1,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range successCase {
|
for _, tc := range successCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) != 0 {
|
if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) != 0 {
|
||||||
@@ -289,24 +263,21 @@ func TestValidatePodLogOptions(t *testing.T) {
|
|||||||
errorCase := []struct {
|
errorCase := []struct {
|
||||||
name string
|
name string
|
||||||
podLogOptions v1.PodLogOptions
|
podLogOptions v1.PodLogOptions
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Invalid podLogOptions with Negative TailLines",
|
name: "Invalid podLogOptions with Negative TailLines",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
TailLines: &negativeLine,
|
TailLines: &negativeLine,
|
||||||
LimitBytes: &limitBytesGreaterThan1,
|
LimitBytes: &limitBytesGreaterThan1,
|
||||||
SinceSeconds: &sinceSecondsGreaterThan1,
|
SinceSeconds: &sinceSecondsGreaterThan1,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Invalid podLogOptions with zero or negative LimitBytes",
|
name: "Invalid podLogOptions with zero or negative LimitBytes",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
TailLines: &positiveLine,
|
TailLines: &positiveLine,
|
||||||
LimitBytes: &limitBytesLessThan1,
|
LimitBytes: &limitBytesLessThan1,
|
||||||
SinceSeconds: &sinceSecondsGreaterThan1,
|
SinceSeconds: &sinceSecondsGreaterThan1,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Invalid podLogOptions with zero or negative SinceSeconds",
|
name: "Invalid podLogOptions with zero or negative SinceSeconds",
|
||||||
podLogOptions: v1.PodLogOptions{
|
podLogOptions: v1.PodLogOptions{
|
||||||
TailLines: &negativeLine,
|
TailLines: &negativeLine,
|
||||||
@@ -321,8 +292,7 @@ func TestValidatePodLogOptions(t *testing.T) {
|
|||||||
SinceSeconds: &sinceSecondsGreaterThan1,
|
SinceSeconds: &sinceSecondsGreaterThan1,
|
||||||
SinceTime: ×tamp,
|
SinceTime: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range errorCase {
|
for _, tc := range errorCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) == 0 {
|
if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) == 0 {
|
||||||
@@ -338,54 +308,37 @@ func TestAccumulateUniqueHostPorts(t *testing.T) {
|
|||||||
containers []v1.Container
|
containers []v1.Container
|
||||||
accumulator *sets.String
|
accumulator *sets.String
|
||||||
fldPath *field.Path
|
fldPath *field.Path
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "HostPort is not allocated while containers use the same port with different protocol",
|
name: "HostPort is not allocated while containers use the same port with different protocol",
|
||||||
containers: []v1.Container{
|
containers: []v1.Container{{
|
||||||
{
|
Ports: []v1.ContainerPort{{
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
Ports: []v1.ContainerPort{{
|
||||||
{
|
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
Protocol: v1.ProtocolTCP,
|
Protocol: v1.ProtocolTCP,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
accumulator: &sets.String{},
|
accumulator: &sets.String{},
|
||||||
fldPath: field.NewPath("spec", "containers"),
|
fldPath: field.NewPath("spec", "containers"),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "HostPort is not allocated while containers use different ports",
|
name: "HostPort is not allocated while containers use different ports",
|
||||||
containers: []v1.Container{
|
containers: []v1.Container{{
|
||||||
{
|
Ports: []v1.ContainerPort{{
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
Ports: []v1.ContainerPort{{
|
||||||
{
|
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8081,
|
HostPort: 8081,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
accumulator: &sets.String{},
|
accumulator: &sets.String{},
|
||||||
fldPath: field.NewPath("spec", "containers"),
|
fldPath: field.NewPath("spec", "containers"),
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range successCase {
|
for _, tc := range successCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) != 0 {
|
if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) != 0 {
|
||||||
@@ -398,54 +351,37 @@ func TestAccumulateUniqueHostPorts(t *testing.T) {
|
|||||||
containers []v1.Container
|
containers []v1.Container
|
||||||
accumulator *sets.String
|
accumulator *sets.String
|
||||||
fldPath *field.Path
|
fldPath *field.Path
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "HostPort is already allocated while containers use the same port with UDP",
|
name: "HostPort is already allocated while containers use the same port with UDP",
|
||||||
containers: []v1.Container{
|
containers: []v1.Container{{
|
||||||
{
|
Ports: []v1.ContainerPort{{
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
Ports: []v1.ContainerPort{{
|
||||||
{
|
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
accumulator: &sets.String{},
|
accumulator: &sets.String{},
|
||||||
fldPath: field.NewPath("spec", "containers"),
|
fldPath: field.NewPath("spec", "containers"),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "HostPort is already allocated",
|
name: "HostPort is already allocated",
|
||||||
containers: []v1.Container{
|
containers: []v1.Container{{
|
||||||
{
|
Ports: []v1.ContainerPort{{
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
Ports: []v1.ContainerPort{{
|
||||||
{
|
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
HostPort: 8081,
|
HostPort: 8081,
|
||||||
Protocol: v1.ProtocolUDP,
|
Protocol: v1.ProtocolUDP,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
accumulator: &sets.String{"8080/UDP": sets.Empty{}},
|
accumulator: &sets.String{"8080/UDP": sets.Empty{}},
|
||||||
fldPath: field.NewPath("spec", "containers"),
|
fldPath: field.NewPath("spec", "containers"),
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range errorCase {
|
for _, tc := range errorCase {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) == 0 {
|
if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) == 0 {
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -477,22 +477,18 @@ func TestValidateIngress(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Spec: networking.IngressSpec{
|
Spec: networking.IngressSpec{
|
||||||
DefaultBackend: &defaultBackend,
|
DefaultBackend: &defaultBackend,
|
||||||
Rules: []networking.IngressRule{
|
Rules: []networking.IngressRule{{
|
||||||
{
|
|
||||||
Host: "foo.bar.com",
|
Host: "foo.bar.com",
|
||||||
IngressRuleValue: networking.IngressRuleValue{
|
IngressRuleValue: networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
PathType: &pathTypeImplementationSpecific,
|
PathType: &pathTypeImplementationSpecific,
|
||||||
Backend: defaultBackend,
|
Backend: defaultBackend,
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Status: networking.IngressStatus{
|
Status: networking.IngressStatus{
|
||||||
LoadBalancer: networking.IngressLoadBalancerStatus{
|
LoadBalancer: networking.IngressLoadBalancerStatus{
|
||||||
@@ -595,8 +591,7 @@ func TestValidateIngress(t *testing.T) {
|
|||||||
tweakIngress: func(ing *networking.Ingress) {
|
tweakIngress: func(ing *networking.Ingress) {
|
||||||
ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{
|
ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
PathType: &pathTypeImplementationSpecific,
|
PathType: &pathTypeImplementationSpecific,
|
||||||
Backend: networking.IngressBackend{
|
Backend: networking.IngressBackend{
|
||||||
@@ -607,8 +602,7 @@ func TestValidateIngress(t *testing.T) {
|
|||||||
Name: "bar",
|
Name: "bar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -620,8 +614,7 @@ func TestValidateIngress(t *testing.T) {
|
|||||||
tweakIngress: func(ing *networking.Ingress) {
|
tweakIngress: func(ing *networking.Ingress) {
|
||||||
ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{
|
ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
PathType: &pathTypeImplementationSpecific,
|
PathType: &pathTypeImplementationSpecific,
|
||||||
Backend: networking.IngressBackend{
|
Backend: networking.IngressBackend{
|
||||||
@@ -632,8 +625,7 @@ func TestValidateIngress(t *testing.T) {
|
|||||||
Name: "bar",
|
Name: "bar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -790,15 +782,13 @@ func TestValidateIngressRuleValue(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
irv := &networking.IngressRuleValue{
|
irv := &networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
Path: testCase.path,
|
Path: testCase.path,
|
||||||
PathType: &testCase.pathType,
|
PathType: &testCase.pathType,
|
||||||
Backend: networking.IngressBackend{
|
Backend: networking.IngressBackend{
|
||||||
Service: &serviceBackend,
|
Service: &serviceBackend,
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{})
|
errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{})
|
||||||
@@ -1638,22 +1628,18 @@ func TestValidateIngressTLS(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Spec: networking.IngressSpec{
|
Spec: networking.IngressSpec{
|
||||||
DefaultBackend: &defaultBackend,
|
DefaultBackend: &defaultBackend,
|
||||||
Rules: []networking.IngressRule{
|
Rules: []networking.IngressRule{{
|
||||||
{
|
|
||||||
Host: "foo.bar.com",
|
Host: "foo.bar.com",
|
||||||
IngressRuleValue: networking.IngressRuleValue{
|
IngressRuleValue: networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
PathType: &pathTypeImplementationSpecific,
|
PathType: &pathTypeImplementationSpecific,
|
||||||
Backend: defaultBackend,
|
Backend: defaultBackend,
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Status: networking.IngressStatus{
|
Status: networking.IngressStatus{
|
||||||
LoadBalancer: networking.IngressLoadBalancerStatus{
|
LoadBalancer: networking.IngressLoadBalancerStatus{
|
||||||
@@ -1670,11 +1656,9 @@ func TestValidateIngressTLS(t *testing.T) {
|
|||||||
wildcardHost := "foo.*.bar.com"
|
wildcardHost := "foo.*.bar.com"
|
||||||
badWildcardTLS := newValid()
|
badWildcardTLS := newValid()
|
||||||
badWildcardTLS.Spec.Rules[0].Host = "*.foo.bar.com"
|
badWildcardTLS.Spec.Rules[0].Host = "*.foo.bar.com"
|
||||||
badWildcardTLS.Spec.TLS = []networking.IngressTLS{
|
badWildcardTLS.Spec.TLS = []networking.IngressTLS{{
|
||||||
{
|
|
||||||
Hosts: []string{wildcardHost},
|
Hosts: []string{wildcardHost},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
badWildcardTLSErr := fmt.Sprintf("spec.tls[0].hosts[0]: Invalid value: '%v'", wildcardHost)
|
badWildcardTLSErr := fmt.Sprintf("spec.tls[0].hosts[0]: Invalid value: '%v'", wildcardHost)
|
||||||
errorCases[badWildcardTLSErr] = badWildcardTLS
|
errorCases[badWildcardTLSErr] = badWildcardTLS
|
||||||
|
|
||||||
@@ -1696,11 +1680,9 @@ func TestValidateIngressTLS(t *testing.T) {
|
|||||||
wildHost := "*.bar.com"
|
wildHost := "*.bar.com"
|
||||||
goodWildcardTLS := newValid()
|
goodWildcardTLS := newValid()
|
||||||
goodWildcardTLS.Spec.Rules[0].Host = "*.bar.com"
|
goodWildcardTLS.Spec.Rules[0].Host = "*.bar.com"
|
||||||
goodWildcardTLS.Spec.TLS = []networking.IngressTLS{
|
goodWildcardTLS.Spec.TLS = []networking.IngressTLS{{
|
||||||
{
|
|
||||||
Hosts: []string{wildHost},
|
Hosts: []string{wildHost},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
validCases[fmt.Sprintf("spec.tls[0].hosts: Valid value: '%v'", wildHost)] = goodWildcardTLS
|
validCases[fmt.Sprintf("spec.tls[0].hosts: Valid value: '%v'", wildHost)] = goodWildcardTLS
|
||||||
for k, v := range validCases {
|
for k, v := range validCases {
|
||||||
errs := validateIngress(&v, IngressValidationOptions{})
|
errs := validateIngress(&v, IngressValidationOptions{})
|
||||||
@@ -1731,21 +1713,17 @@ func TestValidateEmptyIngressTLS(t *testing.T) {
|
|||||||
Namespace: metav1.NamespaceDefault,
|
Namespace: metav1.NamespaceDefault,
|
||||||
},
|
},
|
||||||
Spec: networking.IngressSpec{
|
Spec: networking.IngressSpec{
|
||||||
Rules: []networking.IngressRule{
|
Rules: []networking.IngressRule{{
|
||||||
{
|
|
||||||
Host: "foo.bar.com",
|
Host: "foo.bar.com",
|
||||||
IngressRuleValue: networking.IngressRuleValue{
|
IngressRuleValue: networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
PathType: &pathTypeImplementationSpecific,
|
PathType: &pathTypeImplementationSpecific,
|
||||||
Backend: defaultBackend,
|
Backend: defaultBackend,
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1757,11 +1735,9 @@ func TestValidateEmptyIngressTLS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyTLS.Spec.TLS[0])] = goodEmptyTLS
|
validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyTLS.Spec.TLS[0])] = goodEmptyTLS
|
||||||
goodEmptyHosts := newValid()
|
goodEmptyHosts := newValid()
|
||||||
goodEmptyHosts.Spec.TLS = []networking.IngressTLS{
|
goodEmptyHosts.Spec.TLS = []networking.IngressTLS{{
|
||||||
{
|
|
||||||
Hosts: []string{},
|
Hosts: []string{},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyHosts.Spec.TLS[0])] = goodEmptyHosts
|
validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyHosts.Spec.TLS[0])] = goodEmptyHosts
|
||||||
for k, v := range validCases {
|
for k, v := range validCases {
|
||||||
errs := validateIngress(&v, IngressValidationOptions{})
|
errs := validateIngress(&v, IngressValidationOptions{})
|
||||||
@@ -1791,21 +1767,17 @@ func TestValidateIngressStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Spec: networking.IngressSpec{
|
Spec: networking.IngressSpec{
|
||||||
DefaultBackend: &defaultBackend,
|
DefaultBackend: &defaultBackend,
|
||||||
Rules: []networking.IngressRule{
|
Rules: []networking.IngressRule{{
|
||||||
{
|
|
||||||
Host: "foo.bar.com",
|
Host: "foo.bar.com",
|
||||||
IngressRuleValue: networking.IngressRuleValue{
|
IngressRuleValue: networking.IngressRuleValue{
|
||||||
HTTP: &networking.HTTPIngressRuleValue{
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
Paths: []networking.HTTPIngressPath{
|
Paths: []networking.HTTPIngressPath{{
|
||||||
{
|
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
Backend: defaultBackend,
|
Backend: defaultBackend,
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Status: networking.IngressStatus{
|
Status: networking.IngressStatus{
|
||||||
LoadBalancer: networking.IngressLoadBalancerStatus{
|
LoadBalancer: networking.IngressLoadBalancerStatus{
|
||||||
@@ -1867,17 +1839,13 @@ func TestValidateIngressStatusUpdate(t *testing.T) {
|
|||||||
|
|
||||||
func makeNodeSelector(key string, op api.NodeSelectorOperator, values []string) *api.NodeSelector {
|
func makeNodeSelector(key string, op api.NodeSelectorOperator, values []string) *api.NodeSelector {
|
||||||
return &api.NodeSelector{
|
return &api.NodeSelector{
|
||||||
NodeSelectorTerms: []api.NodeSelectorTerm{
|
NodeSelectorTerms: []api.NodeSelectorTerm{{
|
||||||
{
|
MatchExpressions: []api.NodeSelectorRequirement{{
|
||||||
MatchExpressions: []api.NodeSelectorRequirement{
|
|
||||||
{
|
|
||||||
Key: key,
|
Key: key,
|
||||||
Operator: op,
|
Operator: op,
|
||||||
Values: values,
|
Values: values,
|
||||||
},
|
}},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1901,48 +1869,39 @@ func TestValidateClusterCIDR(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
cc *networking.ClusterCIDR
|
cc *networking.ClusterCIDR
|
||||||
expectErr bool
|
expectErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv4 ClusterCIDR",
|
name: "valid SingleStack IPv4 ClusterCIDR",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits = maxPerNodeHostBits",
|
name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits = maxPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(16, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(16, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits > minPerNodeHostBits",
|
name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits > minPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(4, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(4, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv6 ClusterCIDR",
|
name: "valid SingleStack IPv6 ClusterCIDR",
|
||||||
cc: makeClusterCIDR(8, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits = maxPerNodeHostBit",
|
name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits = maxPerNodeHostBit",
|
||||||
cc: makeClusterCIDR(64, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(64, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits > minPerNodeHostBit",
|
name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits > minPerNodeHostBit",
|
||||||
cc: makeClusterCIDR(4, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(4, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid SingleStack IPv6 ClusterCIDR perNodeHostBits=100",
|
name: "valid SingleStack IPv6 ClusterCIDR perNodeHostBits=100",
|
||||||
cc: makeClusterCIDR(100, "", "fd00:1:1::/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(100, "", "fd00:1:1::/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid DualStack ClusterCIDR",
|
name: "valid DualStack ClusterCIDR",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid DualStack ClusterCIDR, no NodeSelector",
|
name: "valid DualStack ClusterCIDR, no NodeSelector",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", nil),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", nil),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
@@ -1952,8 +1911,7 @@ func TestValidateClusterCIDR(t *testing.T) {
|
|||||||
name: "invalid ClusterCIDR, no IPv4 or IPv6 CIDR",
|
name: "invalid ClusterCIDR, no IPv4 or IPv6 CIDR",
|
||||||
cc: makeClusterCIDR(8, "", "", nil),
|
cc: makeClusterCIDR(8, "", "", nil),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid ClusterCIDR, invalid nodeSelector",
|
name: "invalid ClusterCIDR, invalid nodeSelector",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("NoUppercaseOrSpecialCharsLike=Equals", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("NoUppercaseOrSpecialCharsLike=Equals", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
@@ -1963,13 +1921,11 @@ func TestValidateClusterCIDR(t *testing.T) {
|
|||||||
name: "invalid SingleStack IPv4 ClusterCIDR, invalid spec.IPv4",
|
name: "invalid SingleStack IPv4 ClusterCIDR, invalid spec.IPv4",
|
||||||
cc: makeClusterCIDR(8, "test", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "test", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid Singlestack IPv4 ClusterCIDR, perNodeHostBits > maxPerNodeHostBits",
|
name: "invalid Singlestack IPv4 ClusterCIDR, perNodeHostBits > maxPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(100, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(100, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid SingleStack IPv4 ClusterCIDR, perNodeHostBits < minPerNodeHostBits",
|
name: "invalid SingleStack IPv4 ClusterCIDR, perNodeHostBits < minPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(2, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(2, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
@@ -1979,18 +1935,15 @@ func TestValidateClusterCIDR(t *testing.T) {
|
|||||||
name: "invalid SingleStack IPv6 ClusterCIDR, invalid spec.IPv6",
|
name: "invalid SingleStack IPv6 ClusterCIDR, invalid spec.IPv6",
|
||||||
cc: makeClusterCIDR(8, "", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid SingleStack IPv6 ClusterCIDR, valid IPv4 CIDR in spec.IPv6",
|
name: "invalid SingleStack IPv6 ClusterCIDR, valid IPv4 CIDR in spec.IPv6",
|
||||||
cc: makeClusterCIDR(8, "", "10.2.0.0/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "", "10.2.0.0/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits",
|
name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(12, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(12, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits < minPerNodeHostBits",
|
name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits < minPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(3, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(3, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
@@ -2000,18 +1953,15 @@ func TestValidateClusterCIDR(t *testing.T) {
|
|||||||
name: "invalid DualStack ClusterCIDR, valid spec.IPv4, invalid spec.IPv6",
|
name: "invalid DualStack ClusterCIDR, valid spec.IPv4, invalid spec.IPv6",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid DualStack ClusterCIDR, valid spec.IPv6, invalid spec.IPv4",
|
name: "invalid DualStack ClusterCIDR, valid spec.IPv6, invalid spec.IPv4",
|
||||||
cc: makeClusterCIDR(8, "testv4", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "testv4", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid DualStack ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits",
|
name: "invalid DualStack ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits",
|
||||||
cc: makeClusterCIDR(24, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(24, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid DualStack ClusterCIDR, valid IPv6 CIDR in spec.IPv4",
|
name: "invalid DualStack ClusterCIDR, valid IPv6 CIDR in spec.IPv4",
|
||||||
cc: makeClusterCIDR(8, "fd00::/120", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "fd00::/120", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
@@ -2038,33 +1988,27 @@ func TestValidateClusterConfigUpdate(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
cc *networking.ClusterCIDR
|
cc *networking.ClusterCIDR
|
||||||
expectErr bool
|
expectErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Successful update, no changes to ClusterCIDR.Spec",
|
name: "Successful update, no changes to ClusterCIDR.Spec",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Failed update, update spec.PerNodeHostBits",
|
name: "Failed update, update spec.PerNodeHostBits",
|
||||||
cc: makeClusterCIDR(12, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(12, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Failed update, update spec.IPv4",
|
name: "Failed update, update spec.IPv4",
|
||||||
cc: makeClusterCIDR(8, "10.2.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.2.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Failed update, update spec.IPv6",
|
name: "Failed update, update spec.IPv6",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:2:/112", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:2:/112", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Failed update, update spec.NodeSelector",
|
name: "Failed update, update spec.NodeSelector",
|
||||||
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar2"})),
|
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar2"})),
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
t.Run(testCase.name, func(t *testing.T) {
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
err := ValidateClusterCIDRUpdate(testCase.cc, oldCCC)
|
err := ValidateClusterCIDRUpdate(testCase.cc, oldCCC)
|
||||||
@@ -2244,8 +2188,7 @@ func TestValidateIPAddressUpdate(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
new func(svc *networking.IPAddress) *networking.IPAddress
|
new func(svc *networking.IPAddress) *networking.IPAddress
|
||||||
expectErr bool
|
expectErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Successful update, no changes",
|
name: "Successful update, no changes",
|
||||||
new: func(old *networking.IPAddress) *networking.IPAddress {
|
new: func(old *networking.IPAddress) *networking.IPAddress {
|
||||||
out := old.DeepCopy()
|
out := old.DeepCopy()
|
||||||
@@ -2267,8 +2210,7 @@ func TestValidateIPAddressUpdate(t *testing.T) {
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
}, expectErr: true,
|
}, expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Failed update, delete spec.ParentRef",
|
name: "Failed update, delete spec.ParentRef",
|
||||||
new: func(svc *networking.IPAddress) *networking.IPAddress {
|
new: func(svc *networking.IPAddress) *networking.IPAddress {
|
||||||
out := svc.DeepCopy()
|
out := svc.DeepCopy()
|
||||||
|
@@ -134,8 +134,7 @@ func TestValidateOverhead(t *testing.T) {
|
|||||||
successCase := []struct {
|
successCase := []struct {
|
||||||
Name string
|
Name string
|
||||||
overhead *node.Overhead
|
overhead *node.Overhead
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
Name: "Overhead with valid cpu and memory resources",
|
Name: "Overhead with valid cpu and memory resources",
|
||||||
overhead: &node.Overhead{
|
overhead: &node.Overhead{
|
||||||
PodFixed: core.ResourceList{
|
PodFixed: core.ResourceList{
|
||||||
@@ -143,8 +142,7 @@ func TestValidateOverhead(t *testing.T) {
|
|||||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range successCase {
|
for _, tc := range successCase {
|
||||||
rc := &node.RuntimeClass{
|
rc := &node.RuntimeClass{
|
||||||
@@ -160,16 +158,14 @@ func TestValidateOverhead(t *testing.T) {
|
|||||||
errorCase := []struct {
|
errorCase := []struct {
|
||||||
Name string
|
Name string
|
||||||
overhead *node.Overhead
|
overhead *node.Overhead
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
Name: "Invalid Resources",
|
Name: "Invalid Resources",
|
||||||
overhead: &node.Overhead{
|
overhead: &node.Overhead{
|
||||||
PodFixed: core.ResourceList{
|
PodFixed: core.ResourceList{
|
||||||
core.ResourceName("my.org"): resource.MustParse("10m"),
|
core.ResourceName("my.org"): resource.MustParse("10m"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range errorCase {
|
for _, tc := range errorCase {
|
||||||
rc := &node.RuntimeClass{
|
rc := &node.RuntimeClass{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||||
|
@@ -107,40 +107,35 @@ func TestValidateUnhealthyPodEvictionPolicyDisruptionBudgetSpec(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
pdbSpec policy.PodDisruptionBudgetSpec
|
pdbSpec policy.PodDisruptionBudgetSpec
|
||||||
expectErr bool
|
expectErr bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid nil UnhealthyPodEvictionPolicy",
|
name: "valid nil UnhealthyPodEvictionPolicy",
|
||||||
pdbSpec: policy.PodDisruptionBudgetSpec{
|
pdbSpec: policy.PodDisruptionBudgetSpec{
|
||||||
MinAvailable: &c1,
|
MinAvailable: &c1,
|
||||||
UnhealthyPodEvictionPolicy: nil,
|
UnhealthyPodEvictionPolicy: nil,
|
||||||
},
|
},
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid UnhealthyPodEvictionPolicy",
|
name: "valid UnhealthyPodEvictionPolicy",
|
||||||
pdbSpec: policy.PodDisruptionBudgetSpec{
|
pdbSpec: policy.PodDisruptionBudgetSpec{
|
||||||
MinAvailable: &c1,
|
MinAvailable: &c1,
|
||||||
UnhealthyPodEvictionPolicy: &alwaysAllowPolicy,
|
UnhealthyPodEvictionPolicy: &alwaysAllowPolicy,
|
||||||
},
|
},
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "empty UnhealthyPodEvictionPolicy",
|
name: "empty UnhealthyPodEvictionPolicy",
|
||||||
pdbSpec: policy.PodDisruptionBudgetSpec{
|
pdbSpec: policy.PodDisruptionBudgetSpec{
|
||||||
MinAvailable: &c1,
|
MinAvailable: &c1,
|
||||||
UnhealthyPodEvictionPolicy: new(policy.UnhealthyPodEvictionPolicyType),
|
UnhealthyPodEvictionPolicy: new(policy.UnhealthyPodEvictionPolicyType),
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid UnhealthyPodEvictionPolicy",
|
name: "invalid UnhealthyPodEvictionPolicy",
|
||||||
pdbSpec: policy.PodDisruptionBudgetSpec{
|
pdbSpec: policy.PodDisruptionBudgetSpec{
|
||||||
MinAvailable: &c1,
|
MinAvailable: &c1,
|
||||||
UnhealthyPodEvictionPolicy: &invalidPolicy,
|
UnhealthyPodEvictionPolicy: &invalidPolicy,
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
@@ -162,8 +157,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
pdbStatus policy.PodDisruptionBudgetStatus
|
pdbStatus policy.PodDisruptionBudgetStatus
|
||||||
expectErrForVersion map[schema.GroupVersion]bool
|
expectErrForVersion map[schema.GroupVersion]bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "DisruptionsAllowed: 10",
|
name: "DisruptionsAllowed: 10",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
DisruptionsAllowed: 10,
|
DisruptionsAllowed: 10,
|
||||||
@@ -172,8 +166,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectNoErrors,
|
policy.SchemeGroupVersion: expectNoErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "CurrentHealthy: 5",
|
name: "CurrentHealthy: 5",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
CurrentHealthy: 5,
|
CurrentHealthy: 5,
|
||||||
@@ -182,8 +175,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectNoErrors,
|
policy.SchemeGroupVersion: expectNoErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "DesiredHealthy: 3",
|
name: "DesiredHealthy: 3",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
DesiredHealthy: 3,
|
DesiredHealthy: 3,
|
||||||
@@ -192,8 +184,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectNoErrors,
|
policy.SchemeGroupVersion: expectNoErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ExpectedPods: 2",
|
name: "ExpectedPods: 2",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
ExpectedPods: 2,
|
ExpectedPods: 2,
|
||||||
@@ -202,8 +193,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectNoErrors,
|
policy.SchemeGroupVersion: expectNoErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "DisruptionsAllowed: -10",
|
name: "DisruptionsAllowed: -10",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
DisruptionsAllowed: -10,
|
DisruptionsAllowed: -10,
|
||||||
@@ -212,8 +202,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectErrors,
|
policy.SchemeGroupVersion: expectErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "CurrentHealthy: -5",
|
name: "CurrentHealthy: -5",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
CurrentHealthy: -5,
|
CurrentHealthy: -5,
|
||||||
@@ -222,8 +211,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectErrors,
|
policy.SchemeGroupVersion: expectErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "DesiredHealthy: -3",
|
name: "DesiredHealthy: -3",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
DesiredHealthy: -3,
|
DesiredHealthy: -3,
|
||||||
@@ -232,8 +220,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectErrors,
|
policy.SchemeGroupVersion: expectErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ExpectedPods: -2",
|
name: "ExpectedPods: -2",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
ExpectedPods: -2,
|
ExpectedPods: -2,
|
||||||
@@ -242,12 +229,10 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
policy.SchemeGroupVersion: expectErrors,
|
policy.SchemeGroupVersion: expectErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Conditions valid",
|
name: "Conditions valid",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
Conditions: []metav1.Condition{
|
Conditions: []metav1.Condition{{
|
||||||
{
|
|
||||||
Type: policyv1beta1.DisruptionAllowedCondition,
|
Type: policyv1beta1.DisruptionAllowedCondition,
|
||||||
Status: metav1.ConditionTrue,
|
Status: metav1.ConditionTrue,
|
||||||
LastTransitionTime: metav1.Time{
|
LastTransitionTime: metav1.Time{
|
||||||
@@ -256,34 +241,28 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
|
|||||||
Reason: policyv1beta1.SufficientPodsReason,
|
Reason: policyv1beta1.SufficientPodsReason,
|
||||||
Message: "message",
|
Message: "message",
|
||||||
ObservedGeneration: 3,
|
ObservedGeneration: 3,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectErrForVersion: map[schema.GroupVersion]bool{
|
expectErrForVersion: map[schema.GroupVersion]bool{
|
||||||
policy.SchemeGroupVersion: expectNoErrors,
|
policy.SchemeGroupVersion: expectNoErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
policyv1beta1.SchemeGroupVersion: expectNoErrors,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Conditions not valid",
|
name: "Conditions not valid",
|
||||||
pdbStatus: policy.PodDisruptionBudgetStatus{
|
pdbStatus: policy.PodDisruptionBudgetStatus{
|
||||||
Conditions: []metav1.Condition{
|
Conditions: []metav1.Condition{{
|
||||||
{
|
|
||||||
Type: policyv1beta1.DisruptionAllowedCondition,
|
Type: policyv1beta1.DisruptionAllowedCondition,
|
||||||
Status: metav1.ConditionTrue,
|
Status: metav1.ConditionTrue,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Type: policyv1beta1.DisruptionAllowedCondition,
|
Type: policyv1beta1.DisruptionAllowedCondition,
|
||||||
Status: metav1.ConditionFalse,
|
Status: metav1.ConditionFalse,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectErrForVersion: map[schema.GroupVersion]bool{
|
expectErrForVersion: map[schema.GroupVersion]bool{
|
||||||
policy.SchemeGroupVersion: expectErrors,
|
policy.SchemeGroupVersion: expectErrors,
|
||||||
policyv1beta1.SchemeGroupVersion: expectErrors,
|
policyv1beta1.SchemeGroupVersion: expectErrors,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
for apiVersion, expectErrors := range tc.expectErrForVersion {
|
for apiVersion, expectErrors := range tc.expectErrForVersion {
|
||||||
@@ -1165,23 +1144,19 @@ func TestAllowEphemeralVolumeType(t *testing.T) {
|
|||||||
description string
|
description string
|
||||||
hasGenericVolume bool
|
hasGenericVolume bool
|
||||||
psp func() *policy.PodSecurityPolicy
|
psp func() *policy.PodSecurityPolicy
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
description: "PodSecurityPolicySpec Without GenericVolume",
|
description: "PodSecurityPolicySpec Without GenericVolume",
|
||||||
hasGenericVolume: false,
|
hasGenericVolume: false,
|
||||||
psp: pspWithoutGenericVolume,
|
psp: pspWithoutGenericVolume,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "PodSecurityPolicySpec With GenericVolume",
|
description: "PodSecurityPolicySpec With GenericVolume",
|
||||||
hasGenericVolume: true,
|
hasGenericVolume: true,
|
||||||
psp: pspWithGenericVolume,
|
psp: pspWithGenericVolume,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
description: "is nil",
|
description: "is nil",
|
||||||
hasGenericVolume: false,
|
hasGenericVolume: false,
|
||||||
psp: pspNil,
|
psp: pspNil,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, oldPSPInfo := range pspInfo {
|
for _, oldPSPInfo := range pspInfo {
|
||||||
for _, newPSPInfo := range pspInfo {
|
for _, newPSPInfo := range pspInfo {
|
||||||
|
@@ -402,12 +402,10 @@ func TestValidateRoleNonResourceURL(t *testing.T) {
|
|||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "default",
|
Name: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
NonResourceURLs: []string{"/*"},
|
NonResourceURLs: []string{"/*"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
}.test(t)
|
}.test(t)
|
||||||
@@ -420,13 +418,11 @@ func TestValidateRoleNamespacedNonResourceURL(t *testing.T) {
|
|||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
Name: "default",
|
Name: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
// non-resource URLs are invalid for namespaced rules
|
// non-resource URLs are invalid for namespaced rules
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
NonResourceURLs: []string{"/*"},
|
NonResourceURLs: []string{"/*"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errType: field.ErrorTypeInvalid,
|
errType: field.ErrorTypeInvalid,
|
||||||
@@ -440,12 +436,10 @@ func TestValidateRoleNonResourceURLNoVerbs(t *testing.T) {
|
|||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "default",
|
Name: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
Verbs: []string{},
|
Verbs: []string{},
|
||||||
NonResourceURLs: []string{"/*"},
|
NonResourceURLs: []string{"/*"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errType: field.ErrorTypeRequired,
|
errType: field.ErrorTypeRequired,
|
||||||
@@ -460,14 +454,12 @@ func TestValidateRoleMixedNonResourceAndResource(t *testing.T) {
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
NonResourceURLs: []string{"/*"},
|
NonResourceURLs: []string{"/*"},
|
||||||
APIGroups: []string{"v1"},
|
APIGroups: []string{"v1"},
|
||||||
Resources: []string{"pods"},
|
Resources: []string{"pods"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errType: field.ErrorTypeInvalid,
|
errType: field.ErrorTypeInvalid,
|
||||||
@@ -482,13 +474,11 @@ func TestValidateRoleValidResource(t *testing.T) {
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
APIGroups: []string{"v1"},
|
APIGroups: []string{"v1"},
|
||||||
Resources: []string{"pods"},
|
Resources: []string{"pods"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
}.test(t)
|
}.test(t)
|
||||||
@@ -501,12 +491,10 @@ func TestValidateRoleNoAPIGroup(t *testing.T) {
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
Resources: []string{"pods"},
|
Resources: []string{"pods"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errType: field.ErrorTypeRequired,
|
errType: field.ErrorTypeRequired,
|
||||||
@@ -521,12 +509,10 @@ func TestValidateRoleNoResources(t *testing.T) {
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
Namespace: "default",
|
Namespace: "default",
|
||||||
},
|
},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{{
|
||||||
{
|
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
APIGroups: []string{"v1"},
|
APIGroups: []string{"v1"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errType: field.ErrorTypeRequired,
|
errType: field.ErrorTypeRequired,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -86,22 +86,19 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
configure func(config *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration
|
configure func(config *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration
|
||||||
errMsg string
|
errMsg string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Success",
|
name: "Success",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid NodeLeaseDurationSeconds",
|
name: "invalid NodeLeaseDurationSeconds",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.NodeLeaseDurationSeconds = 0
|
conf.NodeLeaseDurationSeconds = 0
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: nodeLeaseDurationSeconds must be greater than 0",
|
errMsg: "invalid configuration: nodeLeaseDurationSeconds must be greater than 0",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify EnforceNodeAllocatable without enabling CgroupsPerQOS",
|
name: "specify EnforceNodeAllocatable without enabling CgroupsPerQOS",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.CgroupsPerQOS = false
|
conf.CgroupsPerQOS = false
|
||||||
@@ -109,8 +106,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) is not supported unless cgroupsPerQOS (--cgroups-per-qos) is set to true",
|
errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) is not supported unless cgroupsPerQOS (--cgroups-per-qos) is set to true",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify SystemCgroups without CgroupRoot",
|
name: "specify SystemCgroups without CgroupRoot",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.SystemCgroups = "/"
|
conf.SystemCgroups = "/"
|
||||||
@@ -118,32 +114,28 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: systemCgroups (--system-cgroups) was specified and cgroupRoot (--cgroup-root) was not specified",
|
errMsg: "invalid configuration: systemCgroups (--system-cgroups) was specified and cgroupRoot (--cgroup-root) was not specified",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid EventBurst",
|
name: "invalid EventBurst",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EventBurst = -1
|
conf.EventBurst = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: eventBurst (--event-burst) -1 must not be a negative number",
|
errMsg: "invalid configuration: eventBurst (--event-burst) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid EventRecordQPS",
|
name: "invalid EventRecordQPS",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EventRecordQPS = -1
|
conf.EventRecordQPS = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: eventRecordQPS (--event-qps) -1 must not be a negative number",
|
errMsg: "invalid configuration: eventRecordQPS (--event-qps) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid HealthzPort",
|
name: "invalid HealthzPort",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.HealthzPort = 65536
|
conf.HealthzPort = 65536
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: healthzPort (--healthz-port) 65536 must be between 1 and 65535, inclusive",
|
errMsg: "invalid configuration: healthzPort (--healthz-port) 65536 must be between 1 and 65535, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify CPUCFSQuotaPeriod without enabling CPUCFSQuotaPeriod",
|
name: "specify CPUCFSQuotaPeriod without enabling CPUCFSQuotaPeriod",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": false}
|
conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": false}
|
||||||
@@ -151,8 +143,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {200ms} requires feature gate CustomCPUCFSQuotaPeriod",
|
errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {200ms} requires feature gate CustomCPUCFSQuotaPeriod",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid CPUCFSQuotaPeriod",
|
name: "invalid CPUCFSQuotaPeriod",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": true}
|
conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": true}
|
||||||
@@ -160,24 +151,21 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {2s} must be between 1ms and 1sec, inclusive",
|
errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {2s} must be between 1ms and 1sec, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid ImageGCHighThresholdPercent",
|
name: "invalid ImageGCHighThresholdPercent",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ImageGCHighThresholdPercent = 101
|
conf.ImageGCHighThresholdPercent = 101
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: imageGCHighThresholdPercent (--image-gc-high-threshold) 101 must be between 0 and 100, inclusive",
|
errMsg: "invalid configuration: imageGCHighThresholdPercent (--image-gc-high-threshold) 101 must be between 0 and 100, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid ImageGCLowThresholdPercent",
|
name: "invalid ImageGCLowThresholdPercent",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ImageGCLowThresholdPercent = -1
|
conf.ImageGCLowThresholdPercent = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) -1 must be between 0 and 100, inclusive",
|
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) -1 must be between 0 and 100, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ImageGCLowThresholdPercent is equal to ImageGCHighThresholdPercent",
|
name: "ImageGCLowThresholdPercent is equal to ImageGCHighThresholdPercent",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ImageGCHighThresholdPercent = 0
|
conf.ImageGCHighThresholdPercent = 0
|
||||||
@@ -185,8 +173,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 0 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0",
|
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 0 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ImageGCLowThresholdPercent is greater than ImageGCHighThresholdPercent",
|
name: "ImageGCLowThresholdPercent is greater than ImageGCHighThresholdPercent",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ImageGCHighThresholdPercent = 0
|
conf.ImageGCHighThresholdPercent = 0
|
||||||
@@ -194,120 +181,105 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 1 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0",
|
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 1 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid IPTablesDropBit",
|
name: "invalid IPTablesDropBit",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.IPTablesDropBit = 32
|
conf.IPTablesDropBit = 32
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: iptablesDropBit (--iptables-drop-bit) 32 must be between 0 and 31, inclusive",
|
errMsg: "invalid configuration: iptablesDropBit (--iptables-drop-bit) 32 must be between 0 and 31, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid IPTablesMasqueradeBit",
|
name: "invalid IPTablesMasqueradeBit",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.IPTablesMasqueradeBit = 32
|
conf.IPTablesMasqueradeBit = 32
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: iptablesMasqueradeBit (--iptables-masquerade-bit) 32 must be between 0 and 31, inclusive",
|
errMsg: "invalid configuration: iptablesMasqueradeBit (--iptables-masquerade-bit) 32 must be between 0 and 31, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid KubeAPIBurst",
|
name: "invalid KubeAPIBurst",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.KubeAPIBurst = -1
|
conf.KubeAPIBurst = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: kubeAPIBurst (--kube-api-burst) -1 must not be a negative number",
|
errMsg: "invalid configuration: kubeAPIBurst (--kube-api-burst) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid KubeAPIQPS",
|
name: "invalid KubeAPIQPS",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.KubeAPIQPS = -1
|
conf.KubeAPIQPS = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: kubeAPIQPS (--kube-api-qps) -1 must not be a negative number",
|
errMsg: "invalid configuration: kubeAPIQPS (--kube-api-qps) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid NodeStatusMaxImages",
|
name: "invalid NodeStatusMaxImages",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.NodeStatusMaxImages = -2
|
conf.NodeStatusMaxImages = -2
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: nodeStatusMaxImages (--node-status-max-images) -2 must be -1 or greater",
|
errMsg: "invalid configuration: nodeStatusMaxImages (--node-status-max-images) -2 must be -1 or greater",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid MaxOpenFiles",
|
name: "invalid MaxOpenFiles",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.MaxOpenFiles = -1
|
conf.MaxOpenFiles = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: maxOpenFiles (--max-open-files) -1 must not be a negative number",
|
errMsg: "invalid configuration: maxOpenFiles (--max-open-files) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid MaxPods",
|
name: "invalid MaxPods",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.MaxPods = -1
|
conf.MaxPods = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: maxPods (--max-pods) -1 must not be a negative number",
|
errMsg: "invalid configuration: maxPods (--max-pods) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid OOMScoreAdj",
|
name: "invalid OOMScoreAdj",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.OOMScoreAdj = 1001
|
conf.OOMScoreAdj = 1001
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: oomScoreAdj (--oom-score-adj) 1001 must be between -1000 and 1000, inclusive",
|
errMsg: "invalid configuration: oomScoreAdj (--oom-score-adj) 1001 must be between -1000 and 1000, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid PodsPerCore",
|
name: "invalid PodsPerCore",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.PodsPerCore = -1
|
conf.PodsPerCore = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: podsPerCore (--pods-per-core) -1 must not be a negative number",
|
errMsg: "invalid configuration: podsPerCore (--pods-per-core) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid Port",
|
name: "invalid Port",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.Port = 65536
|
conf.Port = 65536
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: port (--port) 65536 must be between 1 and 65535, inclusive",
|
errMsg: "invalid configuration: port (--port) 65536 must be between 1 and 65535, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid ReadOnlyPort",
|
name: "invalid ReadOnlyPort",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ReadOnlyPort = 65536
|
conf.ReadOnlyPort = 65536
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: readOnlyPort (--read-only-port) 65536 must be between 0 and 65535, inclusive",
|
errMsg: "invalid configuration: readOnlyPort (--read-only-port) 65536 must be between 0 and 65535, inclusive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid RegistryBurst",
|
name: "invalid RegistryBurst",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.RegistryBurst = -1
|
conf.RegistryBurst = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: registryBurst (--registry-burst) -1 must not be a negative number",
|
errMsg: "invalid configuration: registryBurst (--registry-burst) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid RegistryPullQPS",
|
name: "invalid RegistryPullQPS",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.RegistryPullQPS = -1
|
conf.RegistryPullQPS = -1
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: registryPullQPS (--registry-qps) -1 must not be a negative number",
|
errMsg: "invalid configuration: registryPullQPS (--registry-qps) -1 must not be a negative number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid MaxParallelImagePulls",
|
name: "invalid MaxParallelImagePulls",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.MaxParallelImagePulls = utilpointer.Int32(0)
|
conf.MaxParallelImagePulls = utilpointer.Int32(0)
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: maxParallelImagePulls 0 must be a positive number",
|
errMsg: "invalid configuration: maxParallelImagePulls 0 must be a positive number",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid MaxParallelImagePulls and SerializeImagePulls combination",
|
name: "invalid MaxParallelImagePulls and SerializeImagePulls combination",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.MaxParallelImagePulls = utilpointer.Int32(3)
|
conf.MaxParallelImagePulls = utilpointer.Int32(3)
|
||||||
@@ -315,16 +287,14 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: maxParallelImagePulls cannot be larger than 1 unless SerializeImagePulls (--serialize-image-pulls) is set to false",
|
errMsg: "invalid configuration: maxParallelImagePulls cannot be larger than 1 unless SerializeImagePulls (--serialize-image-pulls) is set to false",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid MaxParallelImagePulls and SerializeImagePulls combination",
|
name: "valid MaxParallelImagePulls and SerializeImagePulls combination",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.MaxParallelImagePulls = utilpointer.Int32(1)
|
conf.MaxParallelImagePulls = utilpointer.Int32(1)
|
||||||
conf.SerializeImagePulls = true
|
conf.SerializeImagePulls = true
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify ServerTLSBootstrap without enabling RotateKubeletServerCertificate",
|
name: "specify ServerTLSBootstrap without enabling RotateKubeletServerCertificate",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"RotateKubeletServerCertificate": false}
|
conf.FeatureGates = map[string]bool{"RotateKubeletServerCertificate": false}
|
||||||
@@ -332,24 +302,21 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: serverTLSBootstrap true requires feature gate RotateKubeletServerCertificate",
|
errMsg: "invalid configuration: serverTLSBootstrap true requires feature gate RotateKubeletServerCertificate",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid TopologyManagerPolicy",
|
name: "invalid TopologyManagerPolicy",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.TopologyManagerPolicy = "invalid-policy"
|
conf.TopologyManagerPolicy = "invalid-policy"
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: topologyManagerPolicy (--topology-manager-policy) \"invalid-policy\" must be one of: [\"none\" \"best-effort\" \"restricted\" \"single-numa-node\"]",
|
errMsg: "invalid configuration: topologyManagerPolicy (--topology-manager-policy) \"invalid-policy\" must be one of: [\"none\" \"best-effort\" \"restricted\" \"single-numa-node\"]",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid TopologyManagerScope",
|
name: "invalid TopologyManagerScope",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.TopologyManagerScope = "invalid-scope"
|
conf.TopologyManagerScope = "invalid-scope"
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: topologyManagerScope (--topology-manager-scope) \"invalid-scope\" must be one of: \"container\", or \"pod\"",
|
errMsg: "invalid configuration: topologyManagerScope (--topology-manager-scope) \"invalid-scope\" must be one of: \"container\", or \"pod\"",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ShutdownGracePeriodCriticalPods is greater than ShutdownGracePeriod",
|
name: "ShutdownGracePeriodCriticalPods is greater than ShutdownGracePeriod",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
|
||||||
@@ -358,8 +325,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {2s} must be <= shutdownGracePeriod {1s}",
|
errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {2s} must be <= shutdownGracePeriod {1s}",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ShutdownGracePeriod is less than 1 sec",
|
name: "ShutdownGracePeriod is less than 1 sec",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
|
||||||
@@ -367,8 +333,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: shutdownGracePeriod {1ms} must be either zero or otherwise >= 1 sec",
|
errMsg: "invalid configuration: shutdownGracePeriod {1ms} must be either zero or otherwise >= 1 sec",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "ShutdownGracePeriodCriticalPods is less than 1 sec",
|
name: "ShutdownGracePeriodCriticalPods is less than 1 sec",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
|
||||||
@@ -376,8 +341,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {1ms} must be either zero or otherwise >= 1 sec",
|
errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {1ms} must be either zero or otherwise >= 1 sec",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify ShutdownGracePeriod without enabling GracefulNodeShutdown",
|
name: "specify ShutdownGracePeriod without enabling GracefulNodeShutdown",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false}
|
||||||
@@ -385,8 +349,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown",
|
errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify ShutdownGracePeriodCriticalPods without enabling GracefulNodeShutdown",
|
name: "specify ShutdownGracePeriodCriticalPods without enabling GracefulNodeShutdown",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false}
|
||||||
@@ -394,8 +357,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown",
|
errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid MemorySwap.SwapBehavior",
|
name: "invalid MemorySwap.SwapBehavior",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"NodeSwap": true}
|
conf.FeatureGates = map[string]bool{"NodeSwap": true}
|
||||||
@@ -403,8 +365,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: memorySwap.swapBehavior \"invalid-behavior\" must be one of: \"\", \"LimitedSwap\", or \"UnlimitedSwap\"",
|
errMsg: "invalid configuration: memorySwap.swapBehavior \"invalid-behavior\" must be one of: \"\", \"LimitedSwap\", or \"UnlimitedSwap\"",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify MemorySwap.SwapBehavior without enabling NodeSwap",
|
name: "specify MemorySwap.SwapBehavior without enabling NodeSwap",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"NodeSwap": false}
|
conf.FeatureGates = map[string]bool{"NodeSwap": false}
|
||||||
@@ -412,8 +373,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: memorySwap.swapBehavior cannot be set when NodeSwap feature flag is disabled",
|
errMsg: "invalid configuration: memorySwap.swapBehavior cannot be set when NodeSwap feature flag is disabled",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify SystemReservedEnforcementKey without specifying SystemReservedCgroup",
|
name: "specify SystemReservedEnforcementKey without specifying SystemReservedCgroup",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EnforceNodeAllocatable = []string{kubetypes.SystemReservedEnforcementKey}
|
conf.EnforceNodeAllocatable = []string{kubetypes.SystemReservedEnforcementKey}
|
||||||
@@ -421,8 +381,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: systemReservedCgroup (--system-reserved-cgroup) must be specified when \"system-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)",
|
errMsg: "invalid configuration: systemReservedCgroup (--system-reserved-cgroup) must be specified when \"system-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify KubeReservedEnforcementKey without specifying KubeReservedCgroup",
|
name: "specify KubeReservedEnforcementKey without specifying KubeReservedCgroup",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EnforceNodeAllocatable = []string{kubetypes.KubeReservedEnforcementKey}
|
conf.EnforceNodeAllocatable = []string{kubetypes.KubeReservedEnforcementKey}
|
||||||
@@ -430,32 +389,28 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: kubeReservedCgroup (--kube-reserved-cgroup) must be specified when \"kube-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)",
|
errMsg: "invalid configuration: kubeReservedCgroup (--kube-reserved-cgroup) must be specified when \"kube-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify NodeAllocatableNoneKey with additional enforcements",
|
name: "specify NodeAllocatableNoneKey with additional enforcements",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EnforceNodeAllocatable = []string{kubetypes.NodeAllocatableNoneKey, kubetypes.KubeReservedEnforcementKey}
|
conf.EnforceNodeAllocatable = []string{kubetypes.NodeAllocatableNoneKey, kubetypes.KubeReservedEnforcementKey}
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) may not contain additional enforcements when \"none\" is specified",
|
errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) may not contain additional enforcements when \"none\" is specified",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid EnforceNodeAllocatable",
|
name: "invalid EnforceNodeAllocatable",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EnforceNodeAllocatable = []string{"invalid-enforce-node-allocatable"}
|
conf.EnforceNodeAllocatable = []string{"invalid-enforce-node-allocatable"}
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: option \"invalid-enforce-node-allocatable\" specified for enforceNodeAllocatable (--enforce-node-allocatable). Valid options are \"pods\", \"system-reserved\", \"kube-reserved\", or \"none\"",
|
errMsg: "invalid configuration: option \"invalid-enforce-node-allocatable\" specified for enforceNodeAllocatable (--enforce-node-allocatable). Valid options are \"pods\", \"system-reserved\", \"kube-reserved\", or \"none\"",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid HairpinMode",
|
name: "invalid HairpinMode",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.HairpinMode = "invalid-hair-pin-mode"
|
conf.HairpinMode = "invalid-hair-pin-mode"
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: option \"invalid-hair-pin-mode\" specified for hairpinMode (--hairpin-mode). Valid options are \"none\", \"hairpin-veth\" or \"promiscuous-bridge\"",
|
errMsg: "invalid configuration: option \"invalid-hair-pin-mode\" specified for hairpinMode (--hairpin-mode). Valid options are \"none\", \"hairpin-veth\" or \"promiscuous-bridge\"",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify ReservedSystemCPUs with SystemReservedCgroup",
|
name: "specify ReservedSystemCPUs with SystemReservedCgroup",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ReservedSystemCPUs = "0-3"
|
conf.ReservedSystemCPUs = "0-3"
|
||||||
@@ -463,8 +418,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)",
|
errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify ReservedSystemCPUs with KubeReservedCgroup",
|
name: "specify ReservedSystemCPUs with KubeReservedCgroup",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ReservedSystemCPUs = "0-3"
|
conf.ReservedSystemCPUs = "0-3"
|
||||||
@@ -472,16 +426,14 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)",
|
errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid ReservedSystemCPUs",
|
name: "invalid ReservedSystemCPUs",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.ReservedSystemCPUs = "invalid-reserved-system-cpus"
|
conf.ReservedSystemCPUs = "invalid-reserved-system-cpus"
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: unable to parse reservedSystemCPUs (--reserved-cpus) invalid-reserved-system-cpus, error:",
|
errMsg: "invalid configuration: unable to parse reservedSystemCPUs (--reserved-cpus) invalid-reserved-system-cpus, error:",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "enable MemoryQoS without specifying MemoryThrottlingFactor",
|
name: "enable MemoryQoS without specifying MemoryThrottlingFactor",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"MemoryQoS": true}
|
conf.FeatureGates = map[string]bool{"MemoryQoS": true}
|
||||||
@@ -489,16 +441,14 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: memoryThrottlingFactor is required when MemoryQoS feature flag is enabled",
|
errMsg: "invalid configuration: memoryThrottlingFactor is required when MemoryQoS feature flag is enabled",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid MemoryThrottlingFactor",
|
name: "invalid MemoryThrottlingFactor",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.MemoryThrottlingFactor = utilpointer.Float64(1.1)
|
conf.MemoryThrottlingFactor = utilpointer.Float64(1.1)
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: memoryThrottlingFactor 1.1 must be greater than 0 and less than or equal to 1.0",
|
errMsg: "invalid configuration: memoryThrottlingFactor 1.1 must be greater than 0 and less than or equal to 1.0",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid Taint.TimeAdded",
|
name: "invalid Taint.TimeAdded",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
now := metav1.Now()
|
now := metav1.Now()
|
||||||
@@ -506,8 +456,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: taint.TimeAdded is not nil",
|
errMsg: "invalid configuration: taint.TimeAdded is not nil",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify tracing with KubeletTracing disabled",
|
name: "specify tracing with KubeletTracing disabled",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
samplingRate := int32(99999)
|
samplingRate := int32(99999)
|
||||||
@@ -516,8 +465,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: tracing should not be configured if KubeletTracing feature flag is disabled.",
|
errMsg: "invalid configuration: tracing should not be configured if KubeletTracing feature flag is disabled.",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify tracing invalid sampling rate",
|
name: "specify tracing invalid sampling rate",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
samplingRate := int32(-1)
|
samplingRate := int32(-1)
|
||||||
@@ -526,8 +474,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "tracing.samplingRatePerMillion: Invalid value: -1: sampling rate must be positive",
|
errMsg: "tracing.samplingRatePerMillion: Invalid value: -1: sampling rate must be positive",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "specify tracing invalid endpoint",
|
name: "specify tracing invalid endpoint",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
ep := "dn%2s://localhost:4317"
|
ep := "dn%2s://localhost:4317"
|
||||||
@@ -536,42 +483,36 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "tracing.endpoint: Invalid value: \"dn%2s://localhost:4317\": parse \"dn%2s://localhost:4317\": first path segment in URL cannot contain colon",
|
errMsg: "tracing.endpoint: Invalid value: \"dn%2s://localhost:4317\": parse \"dn%2s://localhost:4317\": first path segment in URL cannot contain colon",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid GracefulNodeShutdownBasedOnPodPriority",
|
name: "invalid GracefulNodeShutdownBasedOnPodPriority",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": true}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": true}
|
||||||
conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{
|
conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{{
|
||||||
{
|
|
||||||
Priority: 0,
|
Priority: 0,
|
||||||
ShutdownGracePeriodSeconds: 0,
|
ShutdownGracePeriodSeconds: 0,
|
||||||
}}
|
}}
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: Cannot specify both shutdownGracePeriodByPodPriority and shutdownGracePeriod at the same time",
|
errMsg: "invalid configuration: Cannot specify both shutdownGracePeriodByPodPriority and shutdownGracePeriod at the same time",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "Specifying shutdownGracePeriodByPodPriority without enable GracefulNodeShutdownBasedOnPodPriority",
|
name: "Specifying shutdownGracePeriodByPodPriority without enable GracefulNodeShutdownBasedOnPodPriority",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": false}
|
conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": false}
|
||||||
conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{
|
conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{{
|
||||||
{
|
|
||||||
Priority: 0,
|
Priority: 0,
|
||||||
ShutdownGracePeriodSeconds: 0,
|
ShutdownGracePeriodSeconds: 0,
|
||||||
}}
|
}}
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: Specifying shutdownGracePeriodByPodPriority requires feature gate GracefulNodeShutdownBasedOnPodPriority",
|
errMsg: "invalid configuration: Specifying shutdownGracePeriodByPodPriority requires feature gate GracefulNodeShutdownBasedOnPodPriority",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "enableSystemLogQuery is enabled without NodeLogQuery feature gate",
|
name: "enableSystemLogQuery is enabled without NodeLogQuery feature gate",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.EnableSystemLogQuery = true
|
conf.EnableSystemLogQuery = true
|
||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: NodeLogQuery feature gate is required for enableSystemLogHandler",
|
errMsg: "invalid configuration: NodeLogQuery feature gate is required for enableSystemLogHandler",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "enableSystemLogQuery is enabled without enableSystemLogHandler",
|
name: "enableSystemLogQuery is enabled without enableSystemLogHandler",
|
||||||
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
|
||||||
conf.FeatureGates = map[string]bool{"NodeLogQuery": true}
|
conf.FeatureGates = map[string]bool{"NodeLogQuery": true}
|
||||||
@@ -580,8 +521,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
|||||||
return conf
|
return conf
|
||||||
},
|
},
|
||||||
errMsg: "invalid configuration: enableSystemLogHandler is required for enableSystemLogQuery",
|
errMsg: "invalid configuration: enableSystemLogHandler is required for enableSystemLogQuery",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
@@ -36,8 +36,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
proxyMode = kubeproxyconfig.ProxyModeIPVS
|
proxyMode = kubeproxyconfig.ProxyModeIPVS
|
||||||
}
|
}
|
||||||
successCases := []kubeproxyconfig.KubeProxyConfiguration{
|
successCases := []kubeproxyconfig.KubeProxyConfiguration{{
|
||||||
{
|
|
||||||
BindAddress: "192.168.59.103",
|
BindAddress: "192.168.59.103",
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
HealthzBindAddress: "0.0.0.0:10256",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -59,8 +58,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "192.168.59.103",
|
BindAddress: "192.168.59.103",
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
HealthzBindAddress: "0.0.0.0:10256",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -77,8 +75,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "192.168.59.103",
|
BindAddress: "192.168.59.103",
|
||||||
HealthzBindAddress: "",
|
HealthzBindAddress: "",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -95,8 +92,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "fd00:192:168:59::103",
|
BindAddress: "fd00:192:168:59::103",
|
||||||
HealthzBindAddress: "",
|
HealthzBindAddress: "",
|
||||||
MetricsBindAddress: "[::1]:10249",
|
MetricsBindAddress: "[::1]:10249",
|
||||||
@@ -113,8 +109,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "10.10.12.11",
|
BindAddress: "10.10.12.11",
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
HealthzBindAddress: "0.0.0.0:12345",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -131,8 +126,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "10.10.12.11",
|
BindAddress: "10.10.12.11",
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
HealthzBindAddress: "0.0.0.0:12345",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -149,8 +143,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "10.10.12.11",
|
BindAddress: "10.10.12.11",
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
HealthzBindAddress: "0.0.0.0:12345",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -167,8 +160,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "10.10.12.11",
|
BindAddress: "10.10.12.11",
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
HealthzBindAddress: "0.0.0.0:12345",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -189,8 +181,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
||||||
InterfaceNamePrefix: "vethabcde",
|
InterfaceNamePrefix: "vethabcde",
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
BindAddress: "10.10.12.11",
|
BindAddress: "10.10.12.11",
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
HealthzBindAddress: "0.0.0.0:12345",
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
@@ -211,8 +202,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
|||||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
||||||
BridgeInterface: "avz",
|
BridgeInterface: "avz",
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, successCase := range successCases {
|
for _, successCase := range successCases {
|
||||||
if errs := Validate(&successCase); len(errs) != 0 {
|
if errs := Validate(&successCase); len(errs) != 0 {
|
||||||
|
@@ -57,8 +57,7 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
|||||||
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
||||||
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
||||||
PercentageOfNodesToScore: pointer.Int32(35),
|
PercentageOfNodesToScore: pointer.Int32(35),
|
||||||
Profiles: []config.KubeSchedulerProfile{
|
Profiles: []config.KubeSchedulerProfile{{
|
||||||
{
|
|
||||||
SchedulerName: "me",
|
SchedulerName: "me",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
@@ -68,14 +67,11 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
|||||||
Disabled: []config.Plugin{{Name: "*"}},
|
Disabled: []config.Plugin{{Name: "*"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
SchedulerName: "other",
|
SchedulerName: "other",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
@@ -85,14 +81,11 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
|||||||
Enabled: []config.Plugin{{Name: "CustomBind"}},
|
Enabled: []config.Plugin{{Name: "CustomBind"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
Extenders: []config.Extender{{
|
||||||
Extenders: []config.Extender{
|
|
||||||
{
|
|
||||||
PrioritizeVerb: "prioritize",
|
PrioritizeVerb: "prioritize",
|
||||||
Weight: 1,
|
Weight: 1,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidParallelismValue := validConfig.DeepCopy()
|
invalidParallelismValue := validConfig.DeepCopy()
|
||||||
@@ -145,60 +138,46 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
|
|||||||
extenderNegativeWeight.Extenders[0].Weight = -1
|
extenderNegativeWeight.Extenders[0].Weight = -1
|
||||||
|
|
||||||
invalidNodePercentage := validConfig.DeepCopy()
|
invalidNodePercentage := validConfig.DeepCopy()
|
||||||
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{
|
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
|
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
invalidPluginArgs := validConfig.DeepCopy()
|
invalidPluginArgs := validConfig.DeepCopy()
|
||||||
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{
|
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.InterPodAffinityArgs{},
|
Args: &config.InterPodAffinityArgs{},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
duplicatedPluginConfig := validConfig.DeepCopy()
|
duplicatedPluginConfig := validConfig.DeepCopy()
|
||||||
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{
|
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "config",
|
Name: "config",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Name: "config",
|
Name: "config",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
mismatchQueueSort := validConfig.DeepCopy()
|
mismatchQueueSort := validConfig.DeepCopy()
|
||||||
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{
|
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{{
|
||||||
{
|
|
||||||
SchedulerName: "me",
|
SchedulerName: "me",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
Enabled: []config.Plugin{{Name: "PrioritySort"}},
|
Enabled: []config.Plugin{{Name: "PrioritySort"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "PrioritySort",
|
Name: "PrioritySort",
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
SchedulerName: "other",
|
SchedulerName: "other",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "CustomSort",
|
Name: "CustomSort",
|
||||||
},
|
}},
|
||||||
},
|
}}
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
||||||
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
||||||
@@ -455,8 +434,7 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
|||||||
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
||||||
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
||||||
PercentageOfNodesToScore: pointer.Int32(35),
|
PercentageOfNodesToScore: pointer.Int32(35),
|
||||||
Profiles: []config.KubeSchedulerProfile{
|
Profiles: []config.KubeSchedulerProfile{{
|
||||||
{
|
|
||||||
SchedulerName: "me",
|
SchedulerName: "me",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
@@ -466,14 +444,11 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
|||||||
Disabled: []config.Plugin{{Name: "*"}},
|
Disabled: []config.Plugin{{Name: "*"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
SchedulerName: "other",
|
SchedulerName: "other",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
@@ -483,14 +458,11 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
|||||||
Enabled: []config.Plugin{{Name: "CustomBind"}},
|
Enabled: []config.Plugin{{Name: "CustomBind"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
Extenders: []config.Extender{{
|
||||||
Extenders: []config.Extender{
|
|
||||||
{
|
|
||||||
PrioritizeVerb: "prioritize",
|
PrioritizeVerb: "prioritize",
|
||||||
Weight: 1,
|
Weight: 1,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidParallelismValue := validConfig.DeepCopy()
|
invalidParallelismValue := validConfig.DeepCopy()
|
||||||
@@ -543,20 +515,16 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
|||||||
extenderNegativeWeight.Extenders[0].Weight = -1
|
extenderNegativeWeight.Extenders[0].Weight = -1
|
||||||
|
|
||||||
invalidNodePercentage := validConfig.DeepCopy()
|
invalidNodePercentage := validConfig.DeepCopy()
|
||||||
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{
|
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
|
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
invalidPluginArgs := validConfig.DeepCopy()
|
invalidPluginArgs := validConfig.DeepCopy()
|
||||||
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{
|
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.InterPodAffinityArgs{},
|
Args: &config.InterPodAffinityArgs{},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
duplicatedPlugins := validConfig.DeepCopy()
|
duplicatedPlugins := validConfig.DeepCopy()
|
||||||
duplicatedPlugins.Profiles[0].Plugins.PreEnqueue.Enabled = []config.Plugin{
|
duplicatedPlugins.Profiles[0].Plugins.PreEnqueue.Enabled = []config.Plugin{
|
||||||
@@ -565,44 +533,34 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
duplicatedPluginConfig := validConfig.DeepCopy()
|
duplicatedPluginConfig := validConfig.DeepCopy()
|
||||||
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{
|
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "config",
|
Name: "config",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Name: "config",
|
Name: "config",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
mismatchQueueSort := validConfig.DeepCopy()
|
mismatchQueueSort := validConfig.DeepCopy()
|
||||||
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{
|
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{{
|
||||||
{
|
|
||||||
SchedulerName: "me",
|
SchedulerName: "me",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
Enabled: []config.Plugin{{Name: "PrioritySort"}},
|
Enabled: []config.Plugin{{Name: "PrioritySort"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "PrioritySort",
|
Name: "PrioritySort",
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
SchedulerName: "other",
|
SchedulerName: "other",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "CustomSort",
|
Name: "CustomSort",
|
||||||
},
|
}},
|
||||||
},
|
}}
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
||||||
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
||||||
@@ -858,8 +816,7 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
|||||||
},
|
},
|
||||||
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
PodInitialBackoffSeconds: podInitialBackoffSeconds,
|
||||||
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
PodMaxBackoffSeconds: podMaxBackoffSeconds,
|
||||||
Profiles: []config.KubeSchedulerProfile{
|
Profiles: []config.KubeSchedulerProfile{{
|
||||||
{
|
|
||||||
SchedulerName: "me",
|
SchedulerName: "me",
|
||||||
PercentageOfNodesToScore: pointer.Int32(35),
|
PercentageOfNodesToScore: pointer.Int32(35),
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
@@ -870,14 +827,11 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
|||||||
Disabled: []config.Plugin{{Name: "*"}},
|
Disabled: []config.Plugin{{Name: "*"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
SchedulerName: "other",
|
SchedulerName: "other",
|
||||||
PercentageOfNodesToScore: pointer.Int32(35),
|
PercentageOfNodesToScore: pointer.Int32(35),
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
@@ -888,14 +842,11 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
|||||||
Enabled: []config.Plugin{{Name: "CustomBind"}},
|
Enabled: []config.Plugin{{Name: "CustomBind"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}},
|
||||||
},
|
Extenders: []config.Extender{{
|
||||||
Extenders: []config.Extender{
|
|
||||||
{
|
|
||||||
PrioritizeVerb: "prioritize",
|
PrioritizeVerb: "prioritize",
|
||||||
Weight: 1,
|
Weight: 1,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidParallelismValue := validConfig.DeepCopy()
|
invalidParallelismValue := validConfig.DeepCopy()
|
||||||
@@ -948,60 +899,46 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
|
|||||||
extenderNegativeWeight.Extenders[0].Weight = -1
|
extenderNegativeWeight.Extenders[0].Weight = -1
|
||||||
|
|
||||||
invalidNodePercentage := validConfig.DeepCopy()
|
invalidNodePercentage := validConfig.DeepCopy()
|
||||||
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{
|
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
|
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
invalidPluginArgs := validConfig.DeepCopy()
|
invalidPluginArgs := validConfig.DeepCopy()
|
||||||
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{
|
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "DefaultPreemption",
|
Name: "DefaultPreemption",
|
||||||
Args: &config.InterPodAffinityArgs{},
|
Args: &config.InterPodAffinityArgs{},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
duplicatedPluginConfig := validConfig.DeepCopy()
|
duplicatedPluginConfig := validConfig.DeepCopy()
|
||||||
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{
|
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "config",
|
Name: "config",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Name: "config",
|
Name: "config",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
mismatchQueueSort := validConfig.DeepCopy()
|
mismatchQueueSort := validConfig.DeepCopy()
|
||||||
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{
|
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{{
|
||||||
{
|
|
||||||
SchedulerName: "me",
|
SchedulerName: "me",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
Enabled: []config.Plugin{{Name: "PrioritySort"}},
|
Enabled: []config.Plugin{{Name: "PrioritySort"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "PrioritySort",
|
Name: "PrioritySort",
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
|
||||||
{
|
|
||||||
SchedulerName: "other",
|
SchedulerName: "other",
|
||||||
Plugins: &config.Plugins{
|
Plugins: &config.Plugins{
|
||||||
QueueSort: config.PluginSet{
|
QueueSort: config.PluginSet{
|
||||||
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
Enabled: []config.Plugin{{Name: "CustomSort"}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PluginConfig: []config.PluginConfig{
|
PluginConfig: []config.PluginConfig{{
|
||||||
{
|
|
||||||
Name: "CustomSort",
|
Name: "CustomSort",
|
||||||
},
|
}},
|
||||||
},
|
}}
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
extenderDuplicateManagedResource := validConfig.DeepCopy()
|
||||||
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
|
||||||
|
@@ -27,158 +27,124 @@ func TestValidateConfiguration(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
config eventratelimitapi.Configuration
|
config eventratelimitapi.Configuration
|
||||||
expectedResult bool
|
expectedResult bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid server",
|
name: "valid server",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "Server",
|
Type: "Server",
|
||||||
Burst: 5,
|
Burst: 5,
|
||||||
QPS: 1,
|
QPS: 1,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid namespace",
|
name: "valid namespace",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "Namespace",
|
Type: "Namespace",
|
||||||
Burst: 10,
|
Burst: 10,
|
||||||
QPS: 2,
|
QPS: 2,
|
||||||
CacheSize: 100,
|
CacheSize: 100,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid user",
|
name: "valid user",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "User",
|
Type: "User",
|
||||||
Burst: 10,
|
Burst: 10,
|
||||||
QPS: 2,
|
QPS: 2,
|
||||||
CacheSize: 100,
|
CacheSize: 100,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid source+object",
|
name: "valid source+object",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "SourceAndObject",
|
Type: "SourceAndObject",
|
||||||
Burst: 5,
|
Burst: 5,
|
||||||
QPS: 1,
|
QPS: 1,
|
||||||
CacheSize: 1000,
|
CacheSize: 1000,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid multiple",
|
name: "valid multiple",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "Server",
|
Type: "Server",
|
||||||
Burst: 5,
|
Burst: 5,
|
||||||
QPS: 1,
|
QPS: 1,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Type: "Namespace",
|
Type: "Namespace",
|
||||||
Burst: 10,
|
Burst: 10,
|
||||||
QPS: 2,
|
QPS: 2,
|
||||||
CacheSize: 100,
|
CacheSize: 100,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Type: "SourceAndObject",
|
Type: "SourceAndObject",
|
||||||
Burst: 25,
|
Burst: 25,
|
||||||
QPS: 10,
|
QPS: 10,
|
||||||
CacheSize: 1000,
|
CacheSize: 1000,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: true,
|
expectedResult: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "missing limits",
|
name: "missing limits",
|
||||||
config: eventratelimitapi.Configuration{},
|
config: eventratelimitapi.Configuration{},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "missing type",
|
name: "missing type",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Burst: 25,
|
Burst: 25,
|
||||||
QPS: 10,
|
QPS: 10,
|
||||||
CacheSize: 1000,
|
CacheSize: 1000,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid type",
|
name: "invalid type",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "unknown-type",
|
Type: "unknown-type",
|
||||||
Burst: 25,
|
Burst: 25,
|
||||||
QPS: 10,
|
QPS: 10,
|
||||||
CacheSize: 1000,
|
CacheSize: 1000,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "missing burst",
|
name: "missing burst",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "Server",
|
Type: "Server",
|
||||||
QPS: 1,
|
QPS: 1,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "missing qps",
|
name: "missing qps",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "Server",
|
Type: "Server",
|
||||||
Burst: 5,
|
Burst: 5,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "negative cache size",
|
name: "negative cache size",
|
||||||
config: eventratelimitapi.Configuration{
|
config: eventratelimitapi.Configuration{
|
||||||
Limits: []eventratelimitapi.Limit{
|
Limits: []eventratelimitapi.Limit{{
|
||||||
{
|
|
||||||
Type: "Namespace",
|
Type: "Namespace",
|
||||||
Burst: 10,
|
Burst: 10,
|
||||||
QPS: 2,
|
QPS: 2,
|
||||||
CacheSize: -1,
|
CacheSize: -1,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
errs := ValidateConfiguration(&tc.config)
|
errs := ValidateConfiguration(&tc.config)
|
||||||
if e, a := tc.expectedResult, len(errs) == 0; e != a {
|
if e, a := tc.expectedResult, len(errs) == 0; e != a {
|
||||||
|
@@ -17,9 +17,10 @@ limitations under the License.
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
internalapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction"
|
internalapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateConfiguration(t *testing.T) {
|
func TestValidateConfiguration(t *testing.T) {
|
||||||
@@ -28,8 +29,7 @@ func TestValidateConfiguration(t *testing.T) {
|
|||||||
config internalapi.Configuration
|
config internalapi.Configuration
|
||||||
testName string
|
testName string
|
||||||
testStatus bool
|
testStatus bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
config: internalapi.Configuration{
|
config: internalapi.Configuration{
|
||||||
Default: []api.Toleration{
|
Default: []api.Toleration{
|
||||||
{Key: "foo", Operator: "Exists", Value: "", Effect: "NoExecute", TolerationSeconds: &[]int64{60}[0]},
|
{Key: "foo", Operator: "Exists", Value: "", Effect: "NoExecute", TolerationSeconds: &[]int64{60}[0]},
|
||||||
@@ -44,22 +44,19 @@ func TestValidateConfiguration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
testName: "Valid cases",
|
testName: "Valid cases",
|
||||||
testStatus: true,
|
testStatus: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
config: internalapi.Configuration{
|
config: internalapi.Configuration{
|
||||||
Whitelist: []api.Toleration{{Key: "foo", Operator: "Exists", Value: "bar", Effect: "NoSchedule"}},
|
Whitelist: []api.Toleration{{Key: "foo", Operator: "Exists", Value: "bar", Effect: "NoSchedule"}},
|
||||||
},
|
},
|
||||||
testName: "Invalid case",
|
testName: "Invalid case",
|
||||||
testStatus: false,
|
testStatus: false,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
config: internalapi.Configuration{
|
config: internalapi.Configuration{
|
||||||
Default: []api.Toleration{{Operator: "Equal", Value: "bar", Effect: "NoSchedule"}},
|
Default: []api.Toleration{{Operator: "Equal", Value: "bar", Effect: "NoSchedule"}},
|
||||||
},
|
},
|
||||||
testName: "Invalid case",
|
testName: "Invalid case",
|
||||||
testStatus: false,
|
testStatus: false,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
errs := ValidateConfiguration(&tests[i].config)
|
errs := ValidateConfiguration(&tests[i].config)
|
||||||
|
@@ -17,9 +17,10 @@ limitations under the License.
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateListOptions(t *testing.T) {
|
func TestValidateListOptions(t *testing.T) {
|
||||||
@@ -32,55 +33,47 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
opts internalversion.ListOptions
|
opts internalversion.ListOptions
|
||||||
watchListFeatureEnabled bool
|
watchListFeatureEnabled bool
|
||||||
expectErrors []string
|
expectErrors []string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "valid-default",
|
name: "valid-default",
|
||||||
opts: internalversion.ListOptions{},
|
opts: internalversion.ListOptions{},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid-resourceversionmatch-exact",
|
name: "valid-resourceversionmatch-exact",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
ResourceVersion: "1",
|
ResourceVersion: "1",
|
||||||
ResourceVersionMatch: metav1.ResourceVersionMatchExact,
|
ResourceVersionMatch: metav1.ResourceVersionMatchExact,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid-resourceversionmatch-exact",
|
name: "invalid-resourceversionmatch-exact",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
ResourceVersion: "0",
|
ResourceVersion: "0",
|
||||||
ResourceVersionMatch: metav1.ResourceVersionMatchExact,
|
ResourceVersionMatch: metav1.ResourceVersionMatchExact,
|
||||||
},
|
},
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch \"exact\" is forbidden for resourceVersion \"0\""},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch \"exact\" is forbidden for resourceVersion \"0\""},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid-resourceversionmatch-notolderthan",
|
name: "valid-resourceversionmatch-notolderthan",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
ResourceVersion: "0",
|
ResourceVersion: "0",
|
||||||
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
|
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "invalid-resourceversionmatch",
|
name: "invalid-resourceversionmatch",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
ResourceVersion: "0",
|
ResourceVersion: "0",
|
||||||
ResourceVersionMatch: "foo",
|
ResourceVersionMatch: "foo",
|
||||||
},
|
},
|
||||||
expectErrors: []string{"resourceVersionMatch: Unsupported value: \"foo\": supported values: \"Exact\", \"NotOlderThan\", \"\""},
|
expectErrors: []string{"resourceVersionMatch: Unsupported value: \"foo\": supported values: \"Exact\", \"NotOlderThan\", \"\""},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "list-sendInitialEvents-forbidden",
|
name: "list-sendInitialEvents-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
SendInitialEvents: boolPtrFn(true),
|
SendInitialEvents: boolPtrFn(true),
|
||||||
},
|
},
|
||||||
expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list"},
|
expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list"},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid-watch-default",
|
name: "valid-watch-default",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid-watch-sendInitialEvents-on",
|
name: "valid-watch-sendInitialEvents-on",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -89,8 +82,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
AllowWatchBookmarks: true,
|
AllowWatchBookmarks: true,
|
||||||
},
|
},
|
||||||
watchListFeatureEnabled: true,
|
watchListFeatureEnabled: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "valid-watch-sendInitialEvents-off",
|
name: "valid-watch-sendInitialEvents-off",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -99,24 +91,21 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
AllowWatchBookmarks: true,
|
AllowWatchBookmarks: true,
|
||||||
},
|
},
|
||||||
watchListFeatureEnabled: true,
|
watchListFeatureEnabled: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-resourceversionmatch-without-sendInitialEvents-forbidden",
|
name: "watch-resourceversionmatch-without-sendInitialEvents-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
|
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
|
||||||
},
|
},
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden for watch unless sendInitialEvents is provided"},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden for watch unless sendInitialEvents is provided"},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-without-resourceversionmatch-forbidden",
|
name: "watch-sendInitialEvents-without-resourceversionmatch-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
SendInitialEvents: boolPtrFn(true),
|
SendInitialEvents: boolPtrFn(true),
|
||||||
},
|
},
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-with-exact-resourceversionmatch-forbidden",
|
name: "watch-sendInitialEvents-with-exact-resourceversionmatch-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -126,8 +115,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
watchListFeatureEnabled: true,
|
watchListFeatureEnabled: true,
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"Exact\": supported values: \"NotOlderThan\""},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"Exact\": supported values: \"NotOlderThan\""},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-on-with-empty-resourceversionmatch-forbidden",
|
name: "watch-sendInitialEvents-on-with-empty-resourceversionmatch-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -135,8 +123,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
ResourceVersionMatch: "",
|
ResourceVersionMatch: "",
|
||||||
},
|
},
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-off-with-empty-resourceversionmatch-forbidden",
|
name: "watch-sendInitialEvents-off-with-empty-resourceversionmatch-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -144,8 +131,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
ResourceVersionMatch: "",
|
ResourceVersionMatch: "",
|
||||||
},
|
},
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-with-incorrect-resourceversionmatch-forbidden",
|
name: "watch-sendInitialEvents-with-incorrect-resourceversionmatch-forbidden",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -155,8 +141,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
watchListFeatureEnabled: true,
|
watchListFeatureEnabled: true,
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"incorrect\": supported values: \"NotOlderThan\""},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"incorrect\": supported values: \"NotOlderThan\""},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
// note that validating allowWatchBookmarks would break backward compatibility
|
// note that validating allowWatchBookmarks would break backward compatibility
|
||||||
// because it was possible to request initial events via resourceVersion=0 before this change
|
// because it was possible to request initial events via resourceVersion=0 before this change
|
||||||
name: "watch-sendInitialEvents-no-allowWatchBookmark",
|
name: "watch-sendInitialEvents-no-allowWatchBookmark",
|
||||||
@@ -166,8 +151,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
|
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
|
||||||
},
|
},
|
||||||
watchListFeatureEnabled: true,
|
watchListFeatureEnabled: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-no-watchlist-fg-disabled",
|
name: "watch-sendInitialEvents-no-watchlist-fg-disabled",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -176,8 +160,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
AllowWatchBookmarks: true,
|
AllowWatchBookmarks: true,
|
||||||
},
|
},
|
||||||
expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "watch-sendInitialEvents-no-watchlist-fg-disabled",
|
name: "watch-sendInitialEvents-no-watchlist-fg-disabled",
|
||||||
opts: internalversion.ListOptions{
|
opts: internalversion.ListOptions{
|
||||||
Watch: true,
|
Watch: true,
|
||||||
@@ -188,8 +171,7 @@ func TestValidateListOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
watchListFeatureEnabled: true,
|
watchListFeatureEnabled: true,
|
||||||
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden when continue is provided"},
|
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden when continue is provided"},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
@@ -136,31 +136,26 @@ func TestValidPatchOptions(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
opts metav1.PatchOptions
|
opts metav1.PatchOptions
|
||||||
patchType types.PatchType
|
patchType types.PatchType
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
opts: metav1.PatchOptions{
|
opts: metav1.PatchOptions{
|
||||||
Force: boolPtr(true),
|
Force: boolPtr(true),
|
||||||
FieldManager: "kubectl",
|
FieldManager: "kubectl",
|
||||||
},
|
},
|
||||||
patchType: types.ApplyPatchType,
|
patchType: types.ApplyPatchType,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
opts: metav1.PatchOptions{
|
opts: metav1.PatchOptions{
|
||||||
FieldManager: "kubectl",
|
FieldManager: "kubectl",
|
||||||
},
|
},
|
||||||
patchType: types.ApplyPatchType,
|
patchType: types.ApplyPatchType,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
opts: metav1.PatchOptions{},
|
opts: metav1.PatchOptions{},
|
||||||
patchType: types.MergePatchType,
|
patchType: types.MergePatchType,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
opts: metav1.PatchOptions{
|
opts: metav1.PatchOptions{
|
||||||
FieldManager: "patcher",
|
FieldManager: "patcher",
|
||||||
},
|
},
|
||||||
patchType: types.MergePatchType,
|
patchType: types.MergePatchType,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(fmt.Sprintf("%v", test.opts), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%v", test.opts), func(t *testing.T) {
|
||||||
@@ -243,36 +238,30 @@ func TestValidateFieldManagerInvalid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateManagedFieldsInvalid(t *testing.T) {
|
func TestValidateManagedFieldsInvalid(t *testing.T) {
|
||||||
tests := []metav1.ManagedFieldsEntry{
|
tests := []metav1.ManagedFieldsEntry{{
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationUpdate,
|
Operation: metav1.ManagedFieldsOperationUpdate,
|
||||||
FieldsType: "RandomVersion",
|
FieldsType: "RandomVersion",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Operation: "RandomOperation",
|
Operation: "RandomOperation",
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
// Operation is missing
|
// Operation is missing
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationUpdate,
|
Operation: metav1.ManagedFieldsOperationUpdate,
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
// Invalid fieldManager
|
// Invalid fieldManager
|
||||||
Manager: "field\nmanager",
|
Manager: "field\nmanager",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationApply,
|
Operation: metav1.ManagedFieldsOperationApply,
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
Subresource: "TooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLong",
|
Subresource: "TooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLong",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) {
|
||||||
@@ -285,30 +274,25 @@ func TestValidateManagedFieldsInvalid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateMangedFieldsValid(t *testing.T) {
|
func TestValidateMangedFieldsValid(t *testing.T) {
|
||||||
tests := []metav1.ManagedFieldsEntry{
|
tests := []metav1.ManagedFieldsEntry{{
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationUpdate,
|
Operation: metav1.ManagedFieldsOperationUpdate,
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
// FieldsType is missing
|
// FieldsType is missing
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationUpdate,
|
Operation: metav1.ManagedFieldsOperationUpdate,
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationApply,
|
Operation: metav1.ManagedFieldsOperationApply,
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
Subresource: "scale",
|
Subresource: "scale",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Operation: metav1.ManagedFieldsOperationApply,
|
Operation: metav1.ManagedFieldsOperationApply,
|
||||||
FieldsType: "FieldsV1",
|
FieldsType: "FieldsV1",
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
Manager: "🍔",
|
Manager: "🍔",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) {
|
||||||
@@ -325,8 +309,7 @@ func TestValidateConditions(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
conditions []metav1.Condition
|
conditions []metav1.Condition
|
||||||
validateErrs func(t *testing.T, errs field.ErrorList)
|
validateErrs func(t *testing.T, errs field.ErrorList)
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "bunch-of-invalid-fields",
|
name: "bunch-of-invalid-fields",
|
||||||
conditions: []metav1.Condition{{
|
conditions: []metav1.Condition{{
|
||||||
Type: ":invalid",
|
Type: ":invalid",
|
||||||
@@ -358,27 +341,22 @@ func TestValidateConditions(t *testing.T) {
|
|||||||
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
|
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "duplicates",
|
name: "duplicates",
|
||||||
conditions: []metav1.Condition{{
|
conditions: []metav1.Condition{{
|
||||||
Type: "First",
|
Type: "First",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Type: "Second",
|
Type: "Second",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
Type: "First",
|
Type: "First",
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
||||||
needle := `status.conditions[2].type: Duplicate value: "First"`
|
needle := `status.conditions[2].type: Duplicate value: "First"`
|
||||||
if !hasError(errs, needle) {
|
if !hasError(errs, needle) {
|
||||||
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
|
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "colon-allowed-in-reason",
|
name: "colon-allowed-in-reason",
|
||||||
conditions: []metav1.Condition{{
|
conditions: []metav1.Condition{{
|
||||||
Type: "First",
|
Type: "First",
|
||||||
@@ -390,8 +368,7 @@ func TestValidateConditions(t *testing.T) {
|
|||||||
t.Errorf("has %q in\n%v", needle, errorsAsString(errs))
|
t.Errorf("has %q in\n%v", needle, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "comma-allowed-in-reason",
|
name: "comma-allowed-in-reason",
|
||||||
conditions: []metav1.Condition{{
|
conditions: []metav1.Condition{{
|
||||||
Type: "First",
|
Type: "First",
|
||||||
@@ -403,8 +380,7 @@ func TestValidateConditions(t *testing.T) {
|
|||||||
t.Errorf("has %q in\n%v", needle, errorsAsString(errs))
|
t.Errorf("has %q in\n%v", needle, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "reason-does-not-end-in-delimiter",
|
name: "reason-does-not-end-in-delimiter",
|
||||||
conditions: []metav1.Condition{{
|
conditions: []metav1.Condition{{
|
||||||
Type: "First",
|
Type: "First",
|
||||||
@@ -416,8 +392,7 @@ func TestValidateConditions(t *testing.T) {
|
|||||||
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
|
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
@@ -433,31 +408,25 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
|
|||||||
labelSelector *metav1.LabelSelector
|
labelSelector *metav1.LabelSelector
|
||||||
wantErrorNumber int
|
wantErrorNumber int
|
||||||
validateErrs func(t *testing.T, errs field.ErrorList)
|
validateErrs func(t *testing.T, errs field.ErrorList)
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "Valid LabelSelector",
|
name: "Valid LabelSelector",
|
||||||
labelSelector: &metav1.LabelSelector{
|
labelSelector: &metav1.LabelSelector{
|
||||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
||||||
{
|
|
||||||
Key: "key",
|
Key: "key",
|
||||||
Operator: metav1.LabelSelectorOpIn,
|
Operator: metav1.LabelSelectorOpIn,
|
||||||
Values: []string{"value"},
|
Values: []string{"value"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErrorNumber: 0,
|
wantErrorNumber: 0,
|
||||||
validateErrs: nil,
|
validateErrs: nil,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "MatchExpression's key name isn't valid",
|
name: "MatchExpression's key name isn't valid",
|
||||||
labelSelector: &metav1.LabelSelector{
|
labelSelector: &metav1.LabelSelector{
|
||||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
||||||
{
|
|
||||||
Key: "-key",
|
Key: "-key",
|
||||||
Operator: metav1.LabelSelectorOpIn,
|
Operator: metav1.LabelSelectorOpIn,
|
||||||
Values: []string{"value"},
|
Values: []string{"value"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErrorNumber: 1,
|
wantErrorNumber: 1,
|
||||||
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
||||||
@@ -466,17 +435,14 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
|
|||||||
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
|
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "MatchExpression's operator isn't valid",
|
name: "MatchExpression's operator isn't valid",
|
||||||
labelSelector: &metav1.LabelSelector{
|
labelSelector: &metav1.LabelSelector{
|
||||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
||||||
{
|
|
||||||
Key: "key",
|
Key: "key",
|
||||||
Operator: "abc",
|
Operator: "abc",
|
||||||
Values: []string{"value"},
|
Values: []string{"value"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErrorNumber: 1,
|
wantErrorNumber: 1,
|
||||||
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
||||||
@@ -485,17 +451,14 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
|
|||||||
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
|
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "MatchExpression's value name isn't valid",
|
name: "MatchExpression's value name isn't valid",
|
||||||
labelSelector: &metav1.LabelSelector{
|
labelSelector: &metav1.LabelSelector{
|
||||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
||||||
{
|
|
||||||
Key: "key",
|
Key: "key",
|
||||||
Operator: metav1.LabelSelectorOpIn,
|
Operator: metav1.LabelSelectorOpIn,
|
||||||
Values: []string{"-value"},
|
Values: []string{"-value"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErrorNumber: 1,
|
wantErrorNumber: 1,
|
||||||
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
validateErrs: func(t *testing.T, errs field.ErrorList) {
|
||||||
@@ -504,8 +467,7 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
|
|||||||
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
|
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for index, testCase := range testCases {
|
for index, testCase := range testCases {
|
||||||
t.Run(testCase.name, func(t *testing.T) {
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
allErrs := ValidateLabelSelector(testCase.labelSelector, LabelSelectorValidationOptions{false}, field.NewPath("labelSelector"))
|
allErrs := ValidateLabelSelector(testCase.labelSelector, LabelSelectorValidationOptions{false}, field.NewPath("labelSelector"))
|
||||||
|
@@ -630,33 +630,27 @@ func TestIsFullyQualifiedName(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
targetName string
|
targetName string
|
||||||
err string
|
err string
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "name needs to be fully qualified, i.e., contains at least 2 dots",
|
name: "name needs to be fully qualified, i.e., contains at least 2 dots",
|
||||||
targetName: "k8s.io",
|
targetName: "k8s.io",
|
||||||
err: "should be a domain with at least three segments separated by dots",
|
err: "should be a domain with at least three segments separated by dots",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "name should not include scheme",
|
name: "name should not include scheme",
|
||||||
targetName: "http://foo.k8s.io",
|
targetName: "http://foo.k8s.io",
|
||||||
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
|
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "email should be invalid",
|
name: "email should be invalid",
|
||||||
targetName: "example@foo.k8s.io",
|
targetName: "example@foo.k8s.io",
|
||||||
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
|
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "name cannot be empty",
|
name: "name cannot be empty",
|
||||||
targetName: "",
|
targetName: "",
|
||||||
err: "Required value",
|
err: "Required value",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "name must conform to RFC 1123",
|
name: "name must conform to RFC 1123",
|
||||||
targetName: "A.B.C",
|
targetName: "A.B.C",
|
||||||
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
|
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
for _, tc := range messageTests {
|
for _, tc := range messageTests {
|
||||||
err := IsFullyQualifiedName(field.NewPath(""), tc.targetName).ToAggregate()
|
err := IsFullyQualifiedName(field.NewPath(""), tc.targetName).ToAggregate()
|
||||||
switch {
|
switch {
|
||||||
|
@@ -23,22 +23,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateConfiguration(t *testing.T) {
|
func TestValidateConfiguration(t *testing.T) {
|
||||||
successCases := []resourcequotaapi.Configuration{
|
successCases := []resourcequotaapi.Configuration{{
|
||||||
{
|
LimitedResources: []resourcequotaapi.LimitedResource{{
|
||||||
LimitedResources: []resourcequotaapi.LimitedResource{
|
|
||||||
{
|
|
||||||
Resource: "pods",
|
Resource: "pods",
|
||||||
MatchContains: []string{"requests.cpu"},
|
MatchContains: []string{"requests.cpu"},
|
||||||
},
|
}},
|
||||||
},
|
}, {
|
||||||
},
|
LimitedResources: []resourcequotaapi.LimitedResource{{
|
||||||
{
|
|
||||||
LimitedResources: []resourcequotaapi.LimitedResource{
|
|
||||||
{
|
|
||||||
Resource: "persistentvolumeclaims",
|
Resource: "persistentvolumeclaims",
|
||||||
MatchContains: []string{"requests.storage"},
|
MatchContains: []string{"requests.storage"},
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range successCases {
|
for i := range successCases {
|
||||||
|
@@ -134,11 +134,9 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
policy := audit.Policy{OmitStages: []audit.Stage{
|
policy := audit.Policy{OmitStages: []audit.Stage{
|
||||||
audit.Stage("foo"),
|
audit.Stage("foo"),
|
||||||
},
|
},
|
||||||
Rules: []audit.PolicyRule{
|
Rules: []audit.PolicyRule{{
|
||||||
{
|
|
||||||
Level: audit.LevelMetadata,
|
Level: audit.LevelMetadata,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
errorCases = append(errorCases, policy)
|
errorCases = append(errorCases, policy)
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -748,37 +748,31 @@ func TestErrConfigurationInvalidWithErrorsIs(t *testing.T) {
|
|||||||
err error
|
err error
|
||||||
matchAgainst error
|
matchAgainst error
|
||||||
expectMatch bool
|
expectMatch bool
|
||||||
}{
|
}{{
|
||||||
{
|
|
||||||
name: "no match",
|
name: "no match",
|
||||||
err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")},
|
err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")},
|
||||||
matchAgainst: fmt.Errorf("no entry %s", "here"),
|
matchAgainst: fmt.Errorf("no entry %s", "here"),
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "match via .Is()",
|
name: "match via .Is()",
|
||||||
err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}},
|
err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}},
|
||||||
matchAgainst: errors.New("unauthorized"),
|
matchAgainst: errors.New("unauthorized"),
|
||||||
expectMatch: true,
|
expectMatch: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "match via equality",
|
name: "match via equality",
|
||||||
err: errConfigurationInvalid{errors.New("err"), someError{}},
|
err: errConfigurationInvalid{errors.New("err"), someError{}},
|
||||||
matchAgainst: someError{},
|
matchAgainst: someError{},
|
||||||
expectMatch: true,
|
expectMatch: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "match via nested aggregate",
|
name: "match via nested aggregate",
|
||||||
err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}},
|
err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}},
|
||||||
matchAgainst: someError{},
|
matchAgainst: someError{},
|
||||||
expectMatch: true,
|
expectMatch: true,
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "match via wrapped aggregate",
|
name: "match via wrapped aggregate",
|
||||||
err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}),
|
err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}),
|
||||||
matchAgainst: someError{},
|
matchAgainst: someError{},
|
||||||
expectMatch: true,
|
expectMatch: true,
|
||||||
},
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user