@@ -2,6 +2,7 @@ package collect
22
33import (
44 "context"
5+ "encoding/json"
56 "testing"
67
78 troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
@@ -239,3 +240,99 @@ func Test_deleteImagePullSecret(t *testing.T) {
239240 })
240241 }
241242}
243+
244+ func TestSavePodDetails_StripsPodSpec (t * testing.T ) {
245+ pod := & corev1.Pod {
246+ ObjectMeta : metav1.ObjectMeta {
247+ Name : "test-run-pod" ,
248+ Namespace : "default" ,
249+ Labels : map [string ]string {
250+ "troubleshoot-role" : "run-collector" ,
251+ },
252+ },
253+ Spec : corev1.PodSpec {
254+ NodeName : "test-node" ,
255+ Containers : []corev1.Container {
256+ {
257+ Name : "collector" ,
258+ Image : "busybox" ,
259+ Command : []string {"sh" , "-c" , "echo secret-command" },
260+ Args : []string {"--token" , "super-secret-token" },
261+ Env : []corev1.EnvVar {
262+ {Name : "PASSWORD" , Value : "hunter2" },
263+ {
264+ Name : "API_KEY" ,
265+ ValueFrom : & corev1.EnvVarSource {
266+ SecretKeyRef : & corev1.SecretKeySelector {
267+ LocalObjectReference : corev1.LocalObjectReference {Name : "my-secret" },
268+ Key : "api-key" ,
269+ },
270+ },
271+ },
272+ },
273+ },
274+ },
275+ ImagePullSecrets : []corev1.LocalObjectReference {{Name : "my-pull-secret" }},
276+ Volumes : []corev1.Volume {
277+ {
278+ Name : "secret-vol" ,
279+ VolumeSource : corev1.VolumeSource {
280+ Secret : & corev1.SecretVolumeSource {SecretName : "my-secret" },
281+ },
282+ },
283+ },
284+ },
285+ Status : corev1.PodStatus {
286+ Phase : corev1 .PodSucceeded ,
287+ ContainerStatuses : []corev1.ContainerStatus {
288+ {
289+ Name : "collector" ,
290+ State : corev1.ContainerState {
291+ Terminated : & corev1.ContainerStateTerminated {ExitCode : 0 },
292+ },
293+ },
294+ },
295+ },
296+ }
297+
298+ client := fake .NewSimpleClientset (pod )
299+ collector := & troubleshootv1beta2.RunPod {
300+ Name : "test-collector" ,
301+ Namespace : "default" ,
302+ }
303+
304+ result , err := savePodDetails (context .Background (), client , NewResult (), "" , pod , collector )
305+ require .NoError (t , err )
306+
307+ podKey := "test-collector/test-collector.json"
308+ require .Contains (t , result , podKey )
309+
310+ saved := string (result [podKey ])
311+
312+ // Debugging info must still be present
313+ assert .Contains (t , saved , `"name": "test-run-pod"` )
314+ assert .Contains (t , saved , `"phase": "Succeeded"` )
315+ assert .Contains (t , saved , `"exitCode": 0` )
316+
317+ // Sensitive spec data must not be present
318+ assert .NotContains (t , saved , "hunter2" )
319+ assert .NotContains (t , saved , "super-secret-token" )
320+ assert .NotContains (t , saved , "secret-command" )
321+ assert .NotContains (t , saved , "my-secret" )
322+ assert .NotContains (t , saved , "my-pull-secret" )
323+ assert .NotContains (t , saved , `"command":` )
324+ assert .NotContains (t , saved , `"args":` )
325+ assert .NotContains (t , saved , `"env":` )
326+
327+ // The saved JSON must still unmarshal into a Pod so downstream consumers
328+ // (e.g. goldpinger) can read Name and Status.ContainerStatuses.
329+ var savedPod corev1.Pod
330+ require .NoError (t , json .Unmarshal (result [podKey ], & savedPod ))
331+ assert .Equal (t , "test-run-pod" , savedPod .Name )
332+ assert .Equal (t , corev1 .PodSucceeded , savedPod .Status .Phase )
333+ assert .Len (t , savedPod .Status .ContainerStatuses , 1 )
334+ assert .Equal (t , int32 (0 ), savedPod .Status .ContainerStatuses [0 ].State .Terminated .ExitCode )
335+ assert .Empty (t , savedPod .Spec .Containers )
336+ assert .Empty (t , savedPod .Spec .Volumes )
337+ assert .Empty (t , savedPod .Spec .ImagePullSecrets )
338+ }
0 commit comments