1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: Provide kind list hints to the fake dynamic client. (#9036)

* fix: Provide kind list hints to the fake dynamic client.

If one uses the `cloneList` option of `generate` without this, a panic
occurs.

Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* Added test for `cloneList`.

Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* fix: ttl cleanup not working with cluster wide resources (#9060)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* Fix Helm chart to not error when replicas defined (#9066)

Fixes #8941

Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu>
Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* fix: add nodeSelector to the reports cleanup helm hook (#9065)

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* optimize JSON context processing using in-memory maps (#8322)

* optimize JSON context processing using in memory maps

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix excessive logs

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix mutate resource diff

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* uncomment tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* copy resource, as it can be modified

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* clear prior resource to prevent mutating original

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* linter fix

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix ImageInfo to unstructured conversion

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix custom image extractors

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* do not update mutated resource in JSON context

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* address review comments

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

---------

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Signed-off-by: shuting <shuting@nirmata.com>
Co-authored-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* Ran `gci` to silence a lint warning.

Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

* Added a log message when an invalid or incomplete `cloneList` kind is supplied.

Signed-off-by: Anton Chernev <anton.chernev@gmail.com>

---------

Signed-off-by: Anton Chernev <anton.chernev@gmail.com>
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu>
Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Signed-off-by: shuting <shuting@nirmata.com>
Co-authored-by: Anton Chernev <a-anchernov@expediagroup.com>
Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Co-authored-by: treydock <tdockendorf@osc.edu>
Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
Co-authored-by: Jim Bugwadia <jim@nirmata.com>
Co-authored-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Anton Chernev 2023-12-07 06:03:27 +00:00 committed by GitHub
parent f2561d0095
commit 4d2f7fa8d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 14 deletions

View file

@ -88,22 +88,31 @@ func runTest(out io.Writer, testCase test.TestCase, auditWarn bool) ([]engineapi
}
if rule.Name == res.Rule {
if rule.HasGenerate() {
ruleUnstr, err := generate.GetUnstrRule(rule.Generation.DeepCopy())
if err != nil {
fmt.Fprintf(out, " Error: failed to get unstructured rule (%s)\n", err)
break
}
genClone, _, err := unstructured.NestedMap(ruleUnstr.Object, "clone")
if err != nil {
fmt.Fprintf(out, " Error: failed to read data (%s)\n", err)
break
}
if len(genClone) != 0 {
if len(rule.Generation.CloneList.Kinds) != 0 { // cloneList
// We cannot cast this to an unstructured object because it doesn't have a kind.
if isGit {
ruleToCloneSourceResource[rule.Name] = res.CloneSourceResource
} else {
ruleToCloneSourceResource[rule.Name] = path.GetFullPath(res.CloneSourceResource, testDir)
}
} else { // clone or data
ruleUnstr, err := generate.GetUnstrRule(rule.Generation.DeepCopy())
if err != nil {
fmt.Fprintf(out, " Error: failed to get unstructured rule (%s)\n", err)
break
}
genClone, _, err := unstructured.NestedMap(ruleUnstr.Object, "clone")
if err != nil {
fmt.Fprintf(out, " Error: failed to read data (%s)\n", err)
break
}
if len(genClone) != 0 {
if isGit {
ruleToCloneSourceResource[rule.Name] = res.CloneSourceResource
} else {
ruleToCloneSourceResource[rule.Name] = path.GetFullPath(res.CloneSourceResource, testDir)
}
}
}
}
break

View file

@ -10,6 +10,7 @@ import (
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/log"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/store"
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/background/generate"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
@ -18,6 +19,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
@ -43,7 +45,36 @@ func handleGeneratePolicy(out io.Writer, generateResponse *engineapi.EngineRespo
}
}
c, err := initializeMockController(out, objects)
listKinds := map[schema.GroupVersionResource]string{}
// Collect items in a potential cloneList to provide list kinds to the fake dynamic client.
for _, rule := range autogen.ComputeRules(policyContext.Policy()) {
if !rule.HasGenerate() || len(rule.Generation.CloneList.Kinds) == 0 {
continue
}
for _, kind := range rule.Generation.CloneList.Kinds {
apiVersion, kind := kubeutils.GetKindFromGVK(kind)
if apiVersion == "" || kind == "" {
continue
}
gv, err := schema.ParseGroupVersion(apiVersion)
if err != nil {
fmt.Fprintf(out, "failed to parse group and version from clone list kind %s: %v\n", apiVersion, err)
continue
}
listKinds[schema.GroupVersionResource{
Group: gv.Group,
Version: gv.Version,
Resource: strings.ToLower(kind) + "s",
}] = kind + "List"
}
}
c, err := initializeMockController(out, listKinds, objects)
if err != nil {
fmt.Fprintln(out, "error at controller")
return nil, err
@ -82,8 +113,8 @@ func handleGeneratePolicy(out io.Writer, generateResponse *engineapi.EngineRespo
return newRuleResponse, nil
}
func initializeMockController(out io.Writer, objects []runtime.Object) (*generate.GenerateController, error) {
client, err := dclient.NewFakeClient(runtime.NewScheme(), nil, objects...)
func initializeMockController(out io.Writer, gvrToListKind map[schema.GroupVersionResource]string, objects []runtime.Object) (*generate.GenerateController, error) {
client, err := dclient.NewFakeClient(runtime.NewScheme(), gvrToListKind, objects...)
if err != nil {
fmt.Fprintf(out, "Failed to mock dynamic client")
return nil, err

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: default
labels:
allowedToBeCloned: "true"
type: Opaque
data:
password: MWYyZDFlMmU2N2Rm
---
apiVersion: v1
kind: Secret
metadata:
name: missing-label
namespace: default
type: Opaque
data:
password: MWYyZDFlMmU2N2Rm

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: hello-world-namespace
labels:
allowedToBeCloned: "true"
type: Opaque
data:
password: MWYyZDFlMmU2N2Rm

View file

@ -0,0 +1,17 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: kyverno-test.yaml
policies:
- policy.yaml
resources:
- resource.yaml
results:
- policy: clone-list-secrets
rule: clone-list-labelled-secrets
resources:
- hello-world-namespace
cloneSourceResource: cloneSourceResources.yaml
generatedResource: generatedResource.yaml
kind: Namespace
result: pass

View file

@ -0,0 +1,37 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
annotations:
policies.kyverno.io/category: Sample
policies.kyverno.io/description: 'Secrets like registry credentials often need
to exist in multiple Namespaces so Pods there have access. Manually duplicating
those Secrets is time consuming and error prone. This policy will copy all Secrets
with the appropriate label which exists in the `default` Namespace to new Namespaces
when they are created. It will also push updates to the copied Secrets should the
source Secret be changed.'
policies.kyverno.io/subject: Secret
policies.kyverno.io/title: Clone List Secrets
name: clone-list-secrets
spec:
admission: true
background: true
rules:
- generate:
cloneList:
namespace: default
kinds:
- v1/Secret
- v1/ConfigMap
selector:
matchLabels:
allowedToBeCloned: "true"
namespace: '{{request.object.metadata.name}}'
synchronize: true
match:
any:
- resources:
kinds:
- Namespace
name: clone-list-labelled-secrets
validationFailureAction: Audit

View file

@ -0,0 +1,5 @@
apiVersion: v1
kind: Namespace
metadata:
name: hello-world-namespace
namespace: hello-world-namespace