diff --git a/pkg/kube/pod.go b/pkg/kube/pod.go index c619f16ea1..d1ef53d260 100644 --- a/pkg/kube/pod.go +++ b/pkg/kube/pod.go @@ -46,6 +46,7 @@ const ( PodReadyWaitTimeoutEnv = "KANISTER_POD_READY_WAIT_TIMEOUT" errAccessingNode = "Failed to get node" defaultContainerName = "container" + redactedValue = "XXXXX" ) type VolumeMountOptions struct { @@ -501,36 +502,67 @@ func getRedactedEnvVariables(env []v1.EnvVar) []v1.EnvVar { for i, ev := range env { result[i] = v1.EnvVar{ Name: ev.Name, - Value: "XXXXX", + Value: redactedValue, } } return result } -// getRedactedPod hides all values of env variables from pod, so that it should be safely logged -func getRedactedPod(pod *v1.Pod) *v1.Pod { - if pod == nil { +func getRedactedContainers(containers []v1.Container) []v1.Container { + if len(containers) == 0 { return nil } - result := *pod // Make shallow copy + result := make([]v1.Container, len(containers)) + for i, c := range containers { + result[i] = c + result[i].Env = getRedactedEnvVariables(c.Env) + result[i].Command = getRedactedStringSlice(c.Command) + result[i].Args = getRedactedStringSlice(c.Args) + } + return result +} - getSanitizedContainers := func(containers []v1.Container) []v1.Container { - if len(containers) == 0 { - return nil - } +func getRedactedStringSlice(slice []string) []string { + if len(slice) == 0 { + return nil + } + result := make([]string, len(slice)) + for j := range slice { + result[j] = redactedValue + } + return result +} - result := make([]v1.Container, len(containers)) - for i, c := range containers { - result[i] = c - result[i].Env = getRedactedEnvVariables(c.Env) +func getRedactedPodOverride(podOverride crv1alpha1.JSONMap) crv1alpha1.JSONMap { + if len(podOverride) == 0 { + return nil + } + + result := make(crv1alpha1.JSONMap, len(podOverride)) + for k, v := range podOverride { + if c, ok := v.([]v1.Container); ok { + result[k] = getRedactedContainers(c) + } else { + result[k] = v } - return result } - result.Spec.Containers = getSanitizedContainers(result.Spec.Containers) - result.Spec.InitContainers = getSanitizedContainers(result.Spec.InitContainers) + return result +} + +// getRedactedPod hides all sensitive information from pod object (env variables, commands) +// Should be used when pod structure is logged +func getRedactedPod(pod *v1.Pod) *v1.Pod { + if pod == nil { + return nil + } + + result := *pod // Make shallow copy + + result.Spec.Containers = getRedactedContainers(result.Spec.Containers) + result.Spec.InitContainers = getRedactedContainers(result.Spec.InitContainers) return &result } @@ -544,5 +576,7 @@ func getRedactedOptions(opts *PodOptions) *PodOptions { result := *opts // Make shallow copy result.EnvironmentVariables = getRedactedEnvVariables(result.EnvironmentVariables) + result.Command = getRedactedStringSlice(result.Command) + result.PodOverride = getRedactedPodOverride(result.PodOverride) return &result } diff --git a/pkg/kube/pod_test.go b/pkg/kube/pod_test.go index a5c2152999..bb38e2ba69 100644 --- a/pkg/kube/pod_test.go +++ b/pkg/kube/pod_test.go @@ -941,6 +941,17 @@ func (s *PodSuite) TestGetRedactedOptions(c *C) { {Name: "abc", Value: "def", ValueFrom: &corev1.EnvVarSource{}}, {Name: "ooo", Value: "aaa", ValueFrom: &corev1.EnvVarSource{}}, }, + PodOverride: crv1alpha1.JSONMap{ + "containers": []corev1.Container{{ + Name: "sidecar", + Image: consts.LatestKanisterToolsImage, + Command: []string{"sh", "-c", "echo sidecar"}, + Env: []corev1.EnvVar{ + {Name: "a1", Value: "v1"}, + {Name: "a2", Value: "v2"}, + }, + }}, + }, } po1 := getRedactedOptions(opts) @@ -948,10 +959,40 @@ func (s *PodSuite) TestGetRedactedOptions(c *C) { c.Assert(po1.Namespace, Equals, opts.Namespace) c.Assert(po1.GenerateName, Equals, opts.GenerateName) c.Assert(po1.Image, Equals, opts.Image) - c.Assert(po1.Command, DeepEquals, opts.Command) + c.Assert(po1.Command, DeepEquals, []string{redactedValue, redactedValue, redactedValue}) c.Assert(po1.EnvironmentVariables, DeepEquals, []corev1.EnvVar{ - {Name: "abc", Value: "XXXXX"}, - {Name: "ooo", Value: "XXXXX"}, + {Name: "abc", Value: redactedValue}, + {Name: "ooo", Value: redactedValue}, + }) + c.Assert(po1.PodOverride, DeepEquals, crv1alpha1.JSONMap{ + "containers": []corev1.Container{{ + Name: "sidecar", + Image: consts.LatestKanisterToolsImage, + Command: []string{redactedValue, redactedValue, redactedValue}, + Env: []corev1.EnvVar{ + {Name: "a1", Value: redactedValue}, + {Name: "a2", Value: redactedValue}, + }, + }}, + }) + + po2 := getRedactedOptions(&PodOptions{ + Namespace: s.namespace, + GenerateName: "test-", + Image: consts.LatestKanisterToolsImage, + PodOverride: crv1alpha1.JSONMap{ + "volumes": []corev1.Volume{{Name: "Fake volume"}}, + "containers": 123, // Check that non []corev1.Container value will not break anything + }, + }) + + c.Assert(po2.Namespace, Equals, s.namespace) + c.Assert(po2.Image, Equals, consts.LatestKanisterToolsImage) + c.Assert(po2.Command, IsNil) + c.Assert(po2.EnvironmentVariables, IsNil) + c.Assert(po2.PodOverride, DeepEquals, crv1alpha1.JSONMap{ + "volumes": []corev1.Volume{{Name: "Fake volume"}}, + "containers": 123, }) } @@ -966,14 +1007,16 @@ func (s *PodSuite) TestGetRedactedPod(c *C) { { Name: "c1", Image: "img1", + Args: []string{"a", "b", "c"}, Env: []corev1.EnvVar{ {Name: "ev1", Value: "23", ValueFrom: &corev1.EnvVarSource{}}, {Name: "ev2", Value: "dd", ValueFrom: &corev1.EnvVarSource{}}, }, }, { - Name: "c2", - Image: "img2", + Name: "c2", + Image: "img2", + Command: []string{"sh", "-c", "tail -f /dev/null"}, Env: []corev1.EnvVar{ {Name: "a1", Value: "v1", ValueFrom: &corev1.EnvVarSource{}}, {Name: "a2", Value: "v2", ValueFrom: &corev1.EnvVarSource{}}, @@ -991,17 +1034,19 @@ func (s *PodSuite) TestGetRedactedPod(c *C) { { Name: "c1", Image: "img1", + Args: []string{redactedValue, redactedValue, redactedValue}, Env: []corev1.EnvVar{ - {Name: "ev1", Value: "XXXXX"}, - {Name: "ev2", Value: "XXXXX"}, + {Name: "ev1", Value: redactedValue}, + {Name: "ev2", Value: redactedValue}, }, }, { - Name: "c2", - Image: "img2", + Name: "c2", + Image: "img2", + Command: []string{redactedValue, redactedValue, redactedValue}, Env: []corev1.EnvVar{ - {Name: "a1", Value: "XXXXX"}, - {Name: "a2", Value: "XXXXX"}, + {Name: "a1", Value: redactedValue}, + {Name: "a2", Value: redactedValue}, }, }, })