Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement functions to find referencing ConfigMaps and Secrets in Kubernetes manifests #5409

Merged
merged 1 commit into from
Dec 12, 2024

Conversation

Warashi
Copy link
Contributor

@Warashi Warashi commented Dec 11, 2024

What this PR does:

as title

Why we need it:

I want to implement annotateConfigHash in the k8s plugin.
To implement this, we need to find the configmap and secrets referenced in the deployments.

// annotateConfigHash appends a hash annotation into the workload manifests.
// The hash value is calculated by hashing the content of all configmaps/secrets
// that are referenced by the workload.
// This appending ensures that the workload should be restarted when
// one of its configurations changed.
func annotateConfigHash(manifests []provider.Manifest) error {

Which issue(s) this PR fixes:

Part of #4980

Does this PR introduce a user-facing change?: No

  • How are users affected by this change:
  • Is this breaking change:
  • How to migrate (if breaking change):

…ernetes manifests

Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]>
Copy link

codecov bot commented Dec 11, 2024

Codecov Report

Attention: Patch coverage is 82.35294% with 12 lines in your changes missing coverage. Please review.

Project coverage is 25.81%. Comparing base (e276b89) to head (52a8371).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...p/pipedv1/plugin/kubernetes/provider/deployment.go 82.35% 8 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5409      +/-   ##
==========================================
+ Coverage   25.74%   25.81%   +0.06%     
==========================================
  Files         449      450       +1     
  Lines       48452    48520      +68     
==========================================
+ Hits        12474    12524      +50     
- Misses      35005    35019      +14     
- Partials      973      977       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

}
}

func TestFindReferencingConfigMaps(t *testing.T) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is mainly copied from below

func TestFindReferencingConfigMapsInDeployment(t *testing.T) {

}
}

func TestFindReferencingSecrets(t *testing.T) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is mainly copied from below

func TestFindReferencingSecretsInDeployment(t *testing.T) {

// - spec.template.spec.initContainers.envFrom.configMapRef.name
// - spec.template.spec.containers.env.valueFrom.configMapKeyRef.name
// - spec.template.spec.containers.envFrom.configMapRef.name
func FindReferencingConfigMaps(m *unstructured.Unstructured) []string {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this function with the reference below.

func FindReferencingConfigMapsInDeployment(d *appsv1.Deployment) []string {

// - spec.template.spec.initContainers.envFrom.secretRef.name
// - spec.template.spec.containers.env.valueFrom.secretKeyRef.name
// - spec.template.spec.containers.envFrom.secretRef.name
func FindReferencingSecrets(m *unstructured.Unstructured) []string {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this function with the reference below.

func FindReferencingSecretsInDeployment(d *appsv1.Deployment) []string {

Comment on lines +93 to +96
// nestedStringSlice extracts a string slice from the given object by following the fields.
// It returns the extracted string slice.
// If there is []map[string]any in the middle of the fields, it will be flattened.
func nestedStringSlice(obj any, fields ...string) []string {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to convert the unstructured.Unstructured to appsv1.Deployment or something, so I implemented this.
We cannot use unstructured.NestedStringSlice because it handles the []map[string]any differently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Warashi
[Ask]

We cannot use unstructured.NestedStringSlice because it handles the []map[string]any differently.

What's the difference between unstructured.NestedStringSlice and nestedStringSlice ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ffjlabo
unstructured.NestedStringSlice returns an error when there is []map[string]any in the middle of the fields. On the other hand, nestedStringSlice flattens it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Warashi
I got your point. I tried to use unstructured.NestedStringSlice with the data below.
We can't find and flatten slices in the []interface{}{map[string]interface{}{}}.

	obj := map[string]interface{}{
		"spec": map[string]interface{}{
			"template": map[string]interface{}{
				"spec": map[string]interface{}{
					"volumes": []interface{}{
						map[string]interface{}{
							"configMap": map[string]interface{}{
								"name": "canary-by-config-change",
							},
						},
					},
				},
			},
		},
	}

	res, exists, err := unstructured.NestedStringSlice(obj, "spec", "template", "spec", "volumes[]", "configMap", "name")
	assert.True(t, exists)
	assert.NoError(t, err)
	assert.Equal(t, res, []string{"canary-by-config-change"})
=== RUN   Test
        	Error:      	Should be true
        	Error:      	Received unexpected error:
        	            	.spec.template.spec.volumes.configMap accessor error: [map[configMap:map[name:canary-by-config-change]]] is of the type []interface {}, expected map[string]interface{}
        	Error:      	Not equal:
        	            	expected: []string(nil)
        	            	actual  : []string{"canary-by-config-change"}

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -1,2 +1,4 @@
        	            	-([]string) <nil>
        	            	+([]string) (len=1) {
        	            	+ (string) (len=23) "canary-by-config-change"
        	            	+}

        	Test:       	Test

The test for unstructured.NestedFieldNoCopy (used in the unstructured.NestedStringSlice) shows it.
https://github.com/kubernetes/apimachinery/blob/master/pkg/apis/meta/v1/unstructured/helpers_test.go#L122

@Warashi Warashi marked this pull request as ready for review December 11, 2024 01:09
Copy link
Member

@khanhtc1202 khanhtc1202 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Copy link
Member

@ffjlabo ffjlabo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🙆‍♂️

@Warashi Warashi merged commit 6b63206 into master Dec 12, 2024
18 checks passed
@Warashi Warashi deleted the k8s-plugin-find-ref branch December 12, 2024 07:50
@github-actions github-actions bot mentioned this pull request Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants