mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 18:38:40 +00:00
fix: Kyverno apply produces false positives when validating 'empty dangling" tags (#8358)
* fix: verifyImages w/ multiple entries is not consistent Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * clean Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix: Kyverno apply produces false positives when validating 'empty dangling' tags Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
dde312e65d
commit
0688c9b369
4 changed files with 150 additions and 9 deletions
28
cmd/cli/kubectl-kyverno/_testdata/apply/test-1/policy.yaml
Normal file
28
cmd/cli/kubectl-kyverno/_testdata/apply/test-1/policy.yaml
Normal file
|
@ -0,0 +1,28 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: test-policy
|
||||
annotations:
|
||||
policies.kyverno.io/title: "Lol Security Standards"
|
||||
policies.kyverno.io/category: "Lol Security Standards"
|
||||
policies.kyverno.io/severity: "high"
|
||||
policies.kyverno.io/subject: "Pod"
|
||||
spec:
|
||||
background: true
|
||||
failurePolicy: Fail
|
||||
rules:
|
||||
- name: restrict-lol-annotation
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: >-
|
||||
If "lol" annotation is present then
|
||||
its value can be only one of "such lol", "much annotation".
|
||||
pattern:
|
||||
# syntax refdoc: https://kyverno.io/docs/writing-policies/validate/#anchors
|
||||
=(metadata):
|
||||
=(annotations):
|
||||
=(lol): such lol | much annotation
|
101
cmd/cli/kubectl-kyverno/_testdata/apply/test-1/resources.yaml
Normal file
101
cmd/cli/kubectl-kyverno/_testdata/apply/test-1/resources.yaml
Normal file
|
@ -0,0 +1,101 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
name: i-will-fail-the-policy-check
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lol
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
annotations: {}
|
||||
spec:
|
||||
containers:
|
||||
- image: woot
|
||||
name: woot
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
name: no-annotations-pass
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lol
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
# annotations:
|
||||
spec:
|
||||
containers:
|
||||
- image: woot
|
||||
name: woot
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
name: empty-object-pass
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lol
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
annotations: {}
|
||||
spec:
|
||||
containers:
|
||||
- image: woot
|
||||
name: woot
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
name: correct-lol-annotation-pass
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lol
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
annotations:
|
||||
lol: much annotation
|
||||
spec:
|
||||
containers:
|
||||
- image: woot
|
||||
name: woot
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
name: unrelated-annotation-pass
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lol
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lol
|
||||
annotations:
|
||||
much: unrelated
|
||||
spec:
|
||||
containers:
|
||||
- image: woot
|
||||
name: woot
|
|
@ -69,10 +69,11 @@ func Command() *cobra.Command {
|
|||
var removeColor, detailedResults, table bool
|
||||
applyCommandConfig := &ApplyCommandConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "apply",
|
||||
Short: command.FormatDescription(true, websiteUrl, false, description...),
|
||||
Long: command.FormatDescription(false, websiteUrl, false, description...),
|
||||
Example: command.FormatExamples(examples...),
|
||||
Use: "apply",
|
||||
Short: command.FormatDescription(true, websiteUrl, false, description...),
|
||||
Long: command.FormatDescription(false, websiteUrl, false, description...),
|
||||
Example: command.FormatExamples(examples...),
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, policyPaths []string) (err error) {
|
||||
color.InitColors(removeColor)
|
||||
applyCommandConfig.PolicyPaths = policyPaths
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/report"
|
||||
"gotest.tools/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_Apply(t *testing.T) {
|
||||
|
@ -21,7 +21,7 @@ func Test_Apply(t *testing.T) {
|
|||
}
|
||||
// copy disallow_latest_tag.yaml to local path
|
||||
localFileName, err := copyFileToThisDir("../../../../../test/best_practices/disallow_latest_tag.yaml")
|
||||
assert.NilError(t, err)
|
||||
assert.NoError(t, err)
|
||||
defer func() { _ = os.Remove(localFileName) }()
|
||||
|
||||
testcases := []*TestCase{
|
||||
|
@ -322,7 +322,7 @@ func Test_Apply(t *testing.T) {
|
|||
if tc.stdinFile != "" {
|
||||
oldStdin := os.Stdin
|
||||
input, err := os.OpenFile(tc.stdinFile, os.O_RDONLY, 0)
|
||||
assert.NilError(t, err)
|
||||
assert.NoError(t, err)
|
||||
os.Stdin = input
|
||||
defer func() {
|
||||
// Restore original Stdin
|
||||
|
@ -333,10 +333,10 @@ func Test_Apply(t *testing.T) {
|
|||
desc := fmt.Sprintf("Policies: [%s], / Resources: [%s]", strings.Join(tc.config.PolicyPaths, ","), strings.Join(tc.config.ResourcePaths, ","))
|
||||
|
||||
_, _, _, responses, err := tc.config.applyCommandHelper()
|
||||
assert.NilError(t, err, desc)
|
||||
assert.NoError(t, err, desc)
|
||||
|
||||
clustered, _ := report.ComputePolicyReports(tc.config.AuditWarn, responses...)
|
||||
assert.Assert(t, len(clustered) > 0, "policy reports should not be empty: %s", desc)
|
||||
assert.Greater(t, len(clustered), 0, "policy reports should not be empty: %s", desc)
|
||||
combined := []policyreportv1alpha2.ClusterPolicyReport{
|
||||
report.MergeClusterReports(clustered),
|
||||
}
|
||||
|
@ -361,3 +361,14 @@ func copyFileToThisDir(sourceFile string) (string, error) {
|
|||
|
||||
return filepath.Base(sourceFile), os.WriteFile(filepath.Base(sourceFile), input, 0o644)
|
||||
}
|
||||
|
||||
func TestCommand(t *testing.T) {
|
||||
cmd := Command()
|
||||
cmd.SetArgs([]string{
|
||||
"../../_testdata/apply/test-1/policy.yaml",
|
||||
"--resource",
|
||||
"../../_testdata/apply/test-1/resources.yaml",
|
||||
})
|
||||
err := cmd.Execute()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue