mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-30 19:35:06 +00:00
Adding validation to reject audit mode policy creation/updation when mutateDigest is set to true (#6757)
* Adding validation to reject audit mode policy creation/updation when mutateDigest is set to true Signed-off-by: praddy26 <pradeep.vaishnav4@gmail.com> * fix tests Signed-off-by: realshuting <shutting06@gmail.com> --------- Signed-off-by: praddy26 <pradeep.vaishnav4@gmail.com> Signed-off-by: realshuting <shutting06@gmail.com> Co-authored-by: realshuting <shutting06@gmail.com> Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
75280aad28
commit
cc9adc5cd8
7 changed files with 234 additions and 5 deletions
|
@ -199,9 +199,116 @@ func Test_ImageVerification(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAuditFailureAction := false
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
subject := test.subject.Convert()
|
subject := test.subject.Convert()
|
||||||
errs := subject.Validate(path)
|
errs := subject.Validate(isAuditFailureAction, path)
|
||||||
|
var expectedErrs field.ErrorList
|
||||||
|
if test.errors != nil {
|
||||||
|
expectedErrs = test.errors(subject)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, len(errs), len(expectedErrs), fmt.Sprintf("test `%s` error count mismatch, errors %v", test.name, errs))
|
||||||
|
if len(errs) != 0 {
|
||||||
|
assert.DeepEqual(t, errs, expectedErrs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Audit_VerifyImageRule(t *testing.T) {
|
||||||
|
path := field.NewPath("dummy")
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
subject ImageVerification
|
||||||
|
errors func(*ImageVerification) field.ErrorList
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to true for audit failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: true,
|
||||||
|
},
|
||||||
|
errors: func(i *ImageVerification) field.ErrorList {
|
||||||
|
return field.ErrorList{
|
||||||
|
field.Invalid(
|
||||||
|
path.Child("mutateDigest"),
|
||||||
|
i.MutateDigest,
|
||||||
|
"mutateDigest must be set to false for ‘Audit’ failure action"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to false for audit failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuditFailureAction := true // indicates validateFailureAction set to Audit
|
||||||
|
for _, test := range testCases {
|
||||||
|
subject := test.subject.Convert()
|
||||||
|
errs := subject.Validate(isAuditFailureAction, path)
|
||||||
|
var expectedErrs field.ErrorList
|
||||||
|
if test.errors != nil {
|
||||||
|
expectedErrs = test.errors(subject)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, len(errs), len(expectedErrs), fmt.Sprintf("test `%s` error count mismatch, errors %v", test.name, errs))
|
||||||
|
if len(errs) != 0 {
|
||||||
|
assert.DeepEqual(t, errs, expectedErrs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Enforce_VerifyImageRule(t *testing.T) {
|
||||||
|
path := field.NewPath("dummy")
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
subject ImageVerification
|
||||||
|
errors func(*ImageVerification) field.ErrorList
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to true for enforce failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to false for enforce failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuditFailureAction := false // indicates validateFailureAction set to Enforce
|
||||||
|
for _, test := range testCases {
|
||||||
|
subject := test.subject.Convert()
|
||||||
|
errs := subject.Validate(isAuditFailureAction, path)
|
||||||
var expectedErrs field.ErrorList
|
var expectedErrs field.ErrorList
|
||||||
if test.errors != nil {
|
if test.errors != nil {
|
||||||
expectedErrs = test.errors(subject)
|
expectedErrs = test.errors(subject)
|
||||||
|
|
|
@ -258,9 +258,13 @@ func (iv *ImageVerification) GetType() ImageVerificationType {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate implements programmatic validation
|
// Validate implements programmatic validation
|
||||||
func (iv *ImageVerification) Validate(path *field.Path) (errs field.ErrorList) {
|
func (iv *ImageVerification) Validate(isAuditFailureAction bool, path *field.Path) (errs field.ErrorList) {
|
||||||
copy := iv.Convert()
|
copy := iv.Convert()
|
||||||
|
|
||||||
|
if isAuditFailureAction && iv.MutateDigest {
|
||||||
|
errs = append(errs, field.Invalid(path.Child("mutateDigest"), iv.MutateDigest, "mutateDigest must be set to false for ‘Audit’ failure action"))
|
||||||
|
}
|
||||||
|
|
||||||
if len(copy.ImageReferences) == 0 {
|
if len(copy.ImageReferences) == 0 {
|
||||||
errs = append(errs, field.Invalid(path, iv, "An image reference is required"))
|
errs = append(errs, field.Invalid(path, iv, "An image reference is required"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,9 +120,116 @@ func Test_ImageVerification(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAuditFailureAction := false
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
subject := test.subject
|
subject := test.subject
|
||||||
errs := subject.Validate(path)
|
errs := subject.Validate(isAuditFailureAction, path)
|
||||||
|
var expectedErrs field.ErrorList
|
||||||
|
if test.errors != nil {
|
||||||
|
expectedErrs = test.errors(&subject)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, len(errs), len(expectedErrs), fmt.Sprintf("test `%s` error count mismatch, errors %v", test.name, errs))
|
||||||
|
if len(errs) != 0 {
|
||||||
|
assert.DeepEqual(t, errs, expectedErrs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Audit_VerifyImageRule(t *testing.T) {
|
||||||
|
path := field.NewPath("dummy")
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
subject ImageVerification
|
||||||
|
errors func(*ImageVerification) field.ErrorList
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to true for audit failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []kyvernov1.Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: true,
|
||||||
|
},
|
||||||
|
errors: func(i *ImageVerification) field.ErrorList {
|
||||||
|
return field.ErrorList{
|
||||||
|
field.Invalid(
|
||||||
|
path.Child("mutateDigest"),
|
||||||
|
i.MutateDigest,
|
||||||
|
"mutateDigest must be set to false for ‘Audit’ failure action"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to false for audit failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []kyvernov1.Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuditFailureAction := true // indicates validateFailureAction set to Audit
|
||||||
|
for _, test := range testCases {
|
||||||
|
subject := test.subject
|
||||||
|
errs := subject.Validate(isAuditFailureAction, path)
|
||||||
|
var expectedErrs field.ErrorList
|
||||||
|
if test.errors != nil {
|
||||||
|
expectedErrs = test.errors(&subject)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, len(errs), len(expectedErrs), fmt.Sprintf("test `%s` error count mismatch, errors %v", test.name, errs))
|
||||||
|
if len(errs) != 0 {
|
||||||
|
assert.DeepEqual(t, errs, expectedErrs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Enforce_VerifyImageRule(t *testing.T) {
|
||||||
|
path := field.NewPath("dummy")
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
subject ImageVerification
|
||||||
|
errors func(*ImageVerification) field.ErrorList
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to true for enforce failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []kyvernov1.Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mutateDigest set to false for enforce failure action",
|
||||||
|
subject: ImageVerification{
|
||||||
|
ImageReferences: []string{"*"},
|
||||||
|
Attestations: []kyvernov1.Attestation{
|
||||||
|
{
|
||||||
|
PredicateType: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MutateDigest: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuditFailureAction := false // indicates validateFailureAction set to Enforce
|
||||||
|
for _, test := range testCases {
|
||||||
|
subject := test.subject
|
||||||
|
errs := subject.Validate(isAuditFailureAction, path)
|
||||||
var expectedErrs field.ErrorList
|
var expectedErrs field.ErrorList
|
||||||
if test.errors != nil {
|
if test.errors != nil {
|
||||||
expectedErrs = test.errors(&subject)
|
expectedErrs = test.errors(&subject)
|
||||||
|
|
|
@ -63,9 +63,13 @@ type ImageVerification struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate implements programmatic validation
|
// Validate implements programmatic validation
|
||||||
func (iv *ImageVerification) Validate(path *field.Path) (errs field.ErrorList) {
|
func (iv *ImageVerification) Validate(isAuditFailureAction bool, path *field.Path) (errs field.ErrorList) {
|
||||||
copy := iv
|
copy := iv
|
||||||
|
|
||||||
|
if isAuditFailureAction && iv.MutateDigest {
|
||||||
|
errs = append(errs, field.Invalid(path.Child("mutateDigest"), iv.MutateDigest, "mutateDigest must be set to false for ‘Audit’ failure action"))
|
||||||
|
}
|
||||||
|
|
||||||
if len(copy.ImageReferences) == 0 {
|
if len(copy.ImageReferences) == 0 {
|
||||||
errs = append(errs, field.Invalid(path, iv, "An image reference is required"))
|
errs = append(errs, field.Invalid(path, iv, "An image reference is required"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,9 +337,14 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
|
||||||
}
|
}
|
||||||
|
|
||||||
if rule.HasVerifyImages() {
|
if rule.HasVerifyImages() {
|
||||||
|
isAuditFailureAction := false
|
||||||
|
if spec.ValidationFailureAction == kyvernov1.Audit {
|
||||||
|
isAuditFailureAction = true
|
||||||
|
}
|
||||||
|
|
||||||
verifyImagePath := rulePath.Child("verifyImages")
|
verifyImagePath := rulePath.Child("verifyImages")
|
||||||
for index, i := range rule.VerifyImages {
|
for index, i := range rule.VerifyImages {
|
||||||
errs = append(errs, i.Validate(verifyImagePath.Index(index))...)
|
errs = append(errs, i.Validate(isAuditFailureAction, verifyImagePath.Index(index))...)
|
||||||
}
|
}
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
return warnings, errs.ToAggregate()
|
return warnings, errs.ToAggregate()
|
||||||
|
|
|
@ -17,6 +17,7 @@ spec:
|
||||||
- imageReferences:
|
- imageReferences:
|
||||||
- ghcr.io/kyverno/test-verify-image:*
|
- ghcr.io/kyverno/test-verify-image:*
|
||||||
verifyDigest: false
|
verifyDigest: false
|
||||||
|
mutateDigest: false
|
||||||
required: false
|
required: false
|
||||||
attestors:
|
attestors:
|
||||||
- entries:
|
- entries:
|
||||||
|
|
|
@ -17,6 +17,7 @@ spec:
|
||||||
- imageReferences:
|
- imageReferences:
|
||||||
- ghcr.io/kyverno/test-verify-image:*
|
- ghcr.io/kyverno/test-verify-image:*
|
||||||
verifyDigest: false
|
verifyDigest: false
|
||||||
|
mutateDigest: false
|
||||||
required: false
|
required: false
|
||||||
attestors:
|
attestors:
|
||||||
- entries:
|
- entries:
|
||||||
|
|
Loading…
Add table
Reference in a new issue