mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 02:18:15 +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 {
|
||||
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
|
||||
if test.errors != nil {
|
||||
expectedErrs = test.errors(subject)
|
||||
|
|
|
@ -258,9 +258,13 @@ func (iv *ImageVerification) GetType() ImageVerificationType {
|
|||
}
|
||||
|
||||
// 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()
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
if test.errors != nil {
|
||||
expectedErrs = test.errors(&subject)
|
||||
|
|
|
@ -63,9 +63,13 @@ type ImageVerification struct {
|
|||
}
|
||||
|
||||
// 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
|
||||
|
||||
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 {
|
||||
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() {
|
||||
isAuditFailureAction := false
|
||||
if spec.ValidationFailureAction == kyvernov1.Audit {
|
||||
isAuditFailureAction = true
|
||||
}
|
||||
|
||||
verifyImagePath := rulePath.Child("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 {
|
||||
return warnings, errs.ToAggregate()
|
||||
|
|
|
@ -17,6 +17,7 @@ spec:
|
|||
- imageReferences:
|
||||
- ghcr.io/kyverno/test-verify-image:*
|
||||
verifyDigest: false
|
||||
mutateDigest: false
|
||||
required: false
|
||||
attestors:
|
||||
- entries:
|
||||
|
|
|
@ -17,6 +17,7 @@ spec:
|
|||
- imageReferences:
|
||||
- ghcr.io/kyverno/test-verify-image:*
|
||||
verifyDigest: false
|
||||
mutateDigest: false
|
||||
required: false
|
||||
attestors:
|
||||
- entries:
|
||||
|
|
Loading…
Add table
Reference in a new issue