Skip to content

Commit

Permalink
annot-exclusion: fix unit test and use a realistic regex in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
maelvls committed Nov 12, 2024
1 parent d6dd61c commit 365d7a1
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 42 deletions.
6 changes: 2 additions & 4 deletions deploy/charts/venafi-kubernetes-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,11 @@ Control Plane.
You can configure Venafi Kubernetes Agent to exclude some annotations or labels from being pushed to the Venafi Control Plane. All Kubernetes objects are affected. The objects are still pushed, but the specified annotations and labels are removed before being sent to the Venafi Control Plane.
If you would like to exclude annotations keys that contain the word
`secret`, use the regular expression `.*secret.*`. The leading and ending .*
are important if you want to filter out keys that contain `secret` anywhere in the key string.
If you would like to exclude annotations keys that contain the word `word`, use the regular expression `.*word.*`. The leading and ending .* are important if you want to filter out keys that contain `word` anywhere in the key string.
Note that the annotation `kubectl.kubernetes.io/last-applied-configuration` is already excluded by default, you don't need to exclude it explicitly.
Example: excludeAnnotationKeysRegex: [".*secret.*"]
Example: excludeAnnotationKeysRegex: ["kapp\.k14s\.io\/original.*"]
#### **config.excludeLabelKeysRegex** ~ `array`
> Default value:
> ```yaml
Expand Down
2 changes: 1 addition & 1 deletion deploy/charts/venafi-kubernetes-agent/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@
"helm-values.config.configmap.name": {},
"helm-values.config.excludeAnnotationKeysRegex": {
"default": [],
"description": "You can configure Venafi Kubernetes Agent to exclude some annotations or labels from being pushed to the Venafi Control Plane. All Kubernetes objects are affected. The objects are still pushed, but the specified annotations and labels are removed before being sent to the Venafi Control Plane.\n\nIf you would like to exclude annotations keys that contain the word\n`secret`, use the regular expression `.*secret.*`. The leading and ending .*\nare important if you want to filter out keys that contain `secret` anywhere in the key string.\n\nNote that the annotation `kubectl.kubernetes.io/last-applied-configuration` is already excluded by default, you don't need to exclude it explicitly.\n\nExample: excludeAnnotationKeysRegex: [\".*secret.*\"]",
"description": "You can configure Venafi Kubernetes Agent to exclude some annotations or labels from being pushed to the Venafi Control Plane. All Kubernetes objects are affected. The objects are still pushed, but the specified annotations and labels are removed before being sent to the Venafi Control Plane.\n\nIf you would like to exclude annotations keys that contain the word `word`, use the regular expression `.*word.*`. The leading and ending .* are important if you want to filter out keys that contain `word` anywhere in the key string.\n\nNote that the annotation `kubectl.kubernetes.io/last-applied-configuration` is already excluded by default, you don't need to exclude it explicitly.\n\nExample: excludeAnnotationKeysRegex: [\"kapp\\.k14s\\.io\\/original.*\"]",
"items": {},
"type": "array"
},
Expand Down
10 changes: 5 additions & 5 deletions deploy/charts/venafi-kubernetes-agent/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,15 @@ config:
# are affected. The objects are still pushed, but the specified annotations
# and labels are removed before being sent to the Venafi Control Plane.
#
# If you would like to exclude annotations keys that contain the word
# `secret`, use the regular expression `.*secret.*`. The leading and ending .*
# are important if you want to filter out keys that contain `secret` anywhere
# in the key string.
# If you would like to exclude annotations keys that contain the word `word`,
# use the regular expression `.*word.*`. The leading and ending .* are
# important if you want to filter out keys that contain `word` anywhere in the
# key string.
#
# Note that the annotation `kubectl.kubernetes.io/last-applied-configuration`
# is already excluded by default, you don't need to exclude it explicitly.
#
# Example: excludeAnnotationKeysRegex: [".*secret.*"]
# Example: excludeAnnotationKeysRegex: ["kapp\.k14s\.io\/original.*"]
excludeAnnotationKeysRegex: []
excludeLabelKeysRegex: []

Expand Down
73 changes: 41 additions & 32 deletions pkg/datagatherer/k8s/dynamic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ func TestDynamicGatherer_Fetch(t *testing.T) {
// init the datagatherer's informer with the client
// add/delete resources watched by the data gatherer
// check the expected result
emptyScheme := runtime.NewScheme()
tests := map[string]struct {
config ConfigDynamic
excludeAnnotsKeys []string
Expand Down Expand Up @@ -599,31 +598,41 @@ func TestDynamicGatherer_Fetch(t *testing.T) {
},
},
},
"excluded annotations are removed on secrets and CRDs": {
config: ConfigDynamic{GroupVersionResource: schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"}},
excludeAnnotsKeys: []string{".*secret.*"},
addObjects: []runtime.Object{
getObjectAnnot("v1", "Secret", "s0", "n1", map[string]interface{}{"normal-annot": "value"}, nil),
getObjectAnnot("v1", "Secret", "s1", "n1", nil, map[string]interface{}{"normal-label": "value"}),
getObjectAnnot("v1", "Secret", "s2", "n1", map[string]interface{}{"super-secret-annot": "value"}, nil),
getObjectAnnot("v1", "Secret", "s3", "n1", nil, map[string]interface{}{"super-secret-label": "value"}),

getObjectAnnot("route.openshift.io/v1", "Route", "r0", "n1", map[string]interface{}{"normal-annot": "value"}, nil),
getObjectAnnot("route.openshift.io/v1", "Route", "r1", "n1", nil, map[string]interface{}{"normal-label": "value"}),
getObjectAnnot("route.openshift.io/v1", "Route", "r2", "n1", map[string]interface{}{"super-secret-annot": "value"}, nil),
getObjectAnnot("route.openshift.io/v1", "Route", "r3", "n1", nil, map[string]interface{}{"super-secret-label": "value"}),
},
expected: []*api.GatheredResource{
{Resource: getObjectAnnot("v1", "Secret", "s0", "n1", map[string]interface{}{"normal-annot": "value"}, nil)},
{Resource: getObjectAnnot("v1", "Secret", "s1", "n1", nil, map[string]interface{}{"normal-label": "value"})},
{Resource: getObjectAnnot("v1", "Secret", "s2", "n1", nil, nil)},
{Resource: getObjectAnnot("v1", "Secret", "s3", "n1", nil, nil)},

{Resource: getObjectAnnot("route.openshift.io/v1", "Route", "r0", "n1", map[string]interface{}{"normal-annot": "value"}, nil)},
{Resource: getObjectAnnot("route.openshift.io/v1", "Route", "r1", "n1", nil, map[string]interface{}{"normal-label": "value"})},
{Resource: getObjectAnnot("route.openshift.io/v1", "Route", "r2", "n1", nil, nil)},
{Resource: getObjectAnnot("route.openshift.io/v1", "Route", "r3", "n1", nil, nil)},
},
"excluded annotations are removed for unstructured-based gatherers such as secrets": {
config: ConfigDynamic{GroupVersionResource: schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"}},

// To give a realistic regex in this test case, let's use the
// example of the Kapp project that uses four annotations that all
// start with `kapp.k14s.io/original*`. These annotations are
// similar to `kubectl.kubernetes.io/last-applied-configuration` in
// that they may contain sensitive information. From [1], they may
// look like this:
//
// kapp.k14s.io/original: |
// {"apiVersion":"v1","kind":"Secret","spec":{"data": {"password": "cGFzc3dvcmQ=","username": "bXl1c2VybmFtZQ=="}}}
// kapp.k14s.io/original-diff: |
// - type: test
// path: /data
// value:
// password: cygpcGVyUzNjcmV0UEBhc3N3b3JkIQ==
// username: bXl1c2VybmFtZQ==
//
// [1]: https://github.com/carvel-dev/kapp/issues/90#issuecomment-602074356
excludeAnnotsKeys: []string{`kapp\.k14s\.io\/original.*`},

// We haven't found convincing examples of labels that may contain
// sensitive information in the wild, so let's go with a dumb
// example.
excludeLabelKeys: []string{`.*sensitive.*`},

addObjects: []runtime.Object{getObjectAnnot("v1", "Secret", "s0", "n1",
map[string]interface{}{"kapp.k14s.io/original": "foo", "kapp.k14s.io/original-diff": "bar", "normal": "true"},
map[string]interface{}{"is-sensitive-label": "true", "prod": "true"},
)},
expected: []*api.GatheredResource{{Resource: getObjectAnnot("v1", "Secret", "s0", "n1",
map[string]interface{}{"normal": "true"},
map[string]interface{}{"prod": "true"},
)}},
},
}

Expand All @@ -632,12 +641,12 @@ func TestDynamicGatherer_Fetch(t *testing.T) {
var wg sync.WaitGroup
ctx := context.Background()
gvrToListKind := map[schema.GroupVersionResource]string{
schema.GroupVersionResource{Group: "foobar", Version: "v1", Resource: "foos"}: "UnstructuredList",
schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}: "UnstructuredList",
schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"}: "UnstructuredList",
schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"}: "UnstructuredList",
{Group: "foobar", Version: "v1", Resource: "foos"}: "UnstructuredList",
{Group: "apps", Version: "v1", Resource: "deployments"}: "UnstructuredList",
{Group: "", Version: "v1", Resource: "secrets"}: "UnstructuredList",
{Group: "", Version: "v1", Resource: "namespaces"}: "UnstructuredList",
}
cl := fake.NewSimpleDynamicClientWithCustomListKinds(emptyScheme, gvrToListKind, tc.addObjects...)
cl := fake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, tc.addObjects...)
// init the datagatherer's informer with the client
dg, err := tc.config.newDataGathererWithClient(ctx, cl, nil)
if err != nil {
Expand Down Expand Up @@ -927,7 +936,7 @@ func TestDynamicGathererNativeResources_Fetch(t *testing.T) {
// (would require a lot of changes to the testing func). Ideally we
// should test all native resources such as Service, Deployment,
// Ingress, Namespace, and so on.
"excluded annotations are removed native resources: pods, namespaces, etc": {
"excluded annotations are removed for typed resources gatherers such as pods": {
config: ConfigDynamic{GroupVersionResource: podGVR},
excludeAnnotsKeys: []string{"secret"},
excludeLabelKeys: []string{"secret"},
Expand Down

0 comments on commit 365d7a1

Please sign in to comment.