From 95cbfb2e57ff33687ee4f5c42d60be1c523c4d85 Mon Sep 17 00:00:00 2001
From: Eitan Yarmush <eitan.yarmush@solo.io>
Date: Mon, 30 Aug 2021 14:15:01 -0400
Subject: [PATCH] Fix input marshal (#288)

* fix redact to cover last applied config

* working

* added changelog
---
 changelog/v0.19.6/redact-secret-annotations.yaml |  4 ++++
 .../templates/input/input_snapshot.gotmpl        | 16 ++++++++--------
 contrib/pkg/snapshot/redact.go                   | 14 +++++++++++++-
 3 files changed, 25 insertions(+), 9 deletions(-)
 create mode 100644 changelog/v0.19.6/redact-secret-annotations.yaml

diff --git a/changelog/v0.19.6/redact-secret-annotations.yaml b/changelog/v0.19.6/redact-secret-annotations.yaml
new file mode 100644
index 000000000..b7137b169
--- /dev/null
+++ b/changelog/v0.19.6/redact-secret-annotations.yaml
@@ -0,0 +1,4 @@
+changelog:
+  - type: FIX
+    issueLink: https://github.com/solo-io/skv2/issues/289
+    description: Redact secret annotations in case of kubectl apply from JSON marshal of secrets in Output snapshot.
\ No newline at end of file
diff --git a/contrib/codegen/templates/input/input_snapshot.gotmpl b/contrib/codegen/templates/input/input_snapshot.gotmpl
index 74ae6d931..489ab431f 100644
--- a/contrib/codegen/templates/input/input_snapshot.gotmpl
+++ b/contrib/codegen/templates/input/input_snapshot.gotmpl
@@ -225,7 +225,7 @@ func New{{ $snapshotName }}SnapshotFromGeneric(
 {{- $kindLowerCamel := lower_camel $resource.Kind }}
 {{- $kindLowerCamelPlural := pluralize $kindLowerCamel }}
 
-func (s snapshot{{ $snapshotName }}) {{ $kindPlural }}() {{ $set_import_prefix }}.{{ $resource.Kind }}Set {
+func (s *snapshot{{ $snapshotName }}) {{ $kindPlural }}() {{ $set_import_prefix }}.{{ $resource.Kind }}Set {
     return s.{{ $kindLowerCamelPlural }}
 }
 {{- end }}
@@ -233,7 +233,7 @@ func (s snapshot{{ $snapshotName }}) {{ $kindPlural }}() {{ $set_import_prefix }
 
 {{- if $needs_sync_status }}
 
-func (s snapshot{{ $snapshotName }}) SyncStatusesMultiCluster(ctx context.Context, mcClient multicluster.Client, opts {{ $snapshotName }}SyncStatusOptions) error {
+func (s *snapshot{{ $snapshotName }}) SyncStatusesMultiCluster(ctx context.Context, mcClient multicluster.Client, opts {{ $snapshotName }}SyncStatusOptions) error {
 	var errs error
     {{/* generate calls to update status here */}}
     {{- range $group := $groups }}
@@ -262,7 +262,7 @@ func (s snapshot{{ $snapshotName }}) SyncStatusesMultiCluster(ctx context.Contex
 }
 
 
-func (s snapshot{{ $snapshotName }}) SyncStatuses(ctx context.Context, c client.Client, opts {{ $snapshotName }}SyncStatusOptions) error {
+func (s *snapshot{{ $snapshotName }}) SyncStatuses(ctx context.Context, c client.Client, opts {{ $snapshotName }}SyncStatusOptions) error {
     var errs error
     {{/* generate calls to update status here */}}
     {{- range $group := $groups }}
@@ -287,7 +287,7 @@ func (s snapshot{{ $snapshotName }}) SyncStatuses(ctx context.Context, c client.
 
 {{- end }}
 
-func (s snapshot{{ $snapshotName }}) MarshalJSON() ([]byte, error) {
+func (s *snapshot{{ $snapshotName }}) MarshalJSON() ([]byte, error) {
     snapshotMap := map[string]interface{}{"name": s.name}
 {{/* add map contents here */}}
 {{- range $group := $groups }}
@@ -297,7 +297,7 @@ func (s snapshot{{ $snapshotName }}) MarshalJSON() ([]byte, error) {
 {{- $kindLowerCamel := lower_camel $resource.Kind }}
 {{- $kindLowerCamelPlural := pluralize $kindLowerCamel }}
     {{ $kindLowerCamel }}Set := {{ $set_import_prefix }}.New{{ $resource.Kind }}Set()
-    for _, obj := range {{ $kindLowerCamel }}Set.UnsortedList() {
+    for _, obj := range s.{{ $kindLowerCamelPlural }}.UnsortedList() {
         // redact secret data from the snapshot
         obj := snapshotutils.RedactSecretData(obj)
         {{ $kindLowerCamel }}Set.Insert(obj.(*{{ $types_import_prefix }}.{{ $resource.Kind }}))
@@ -308,7 +308,7 @@ func (s snapshot{{ $snapshotName }}) MarshalJSON() ([]byte, error) {
 	return json.Marshal(snapshotMap)
 }
 
-func (s snapshot{{ $snapshotName }}) Clone() {{ $snapshotName }}Snapshot {
+func (s *snapshot{{ $snapshotName }}) Clone() {{ $snapshotName }}Snapshot {
 	return &snapshot{{ $snapshotName }}{
         name: s.name,
 {{/* add map contents here */}}
@@ -322,7 +322,7 @@ func (s snapshot{{ $snapshotName }}) Clone() {{ $snapshotName }}Snapshot {
     }
 }
 
-func (s snapshot{{ $snapshotName }}) Generic() resource.ClusterSnapshot {
+func (s *snapshot{{ $snapshotName }}) Generic() resource.ClusterSnapshot {
     clusterSnapshots := resource.ClusterSnapshot{}
     s.ForEachObject(func(cluster string, gvk schema.GroupVersionKind, obj resource.TypedObject){
         clusterSnapshots.Insert(cluster, gvk, obj)
@@ -332,7 +332,7 @@ func (s snapshot{{ $snapshotName }}) Generic() resource.ClusterSnapshot {
 }
 
 // convert this snapshot to its generic form
-func (s snapshot{{ $snapshotName }}) ForEachObject(handleObject func(cluster string, gvk schema.GroupVersionKind, obj resource.TypedObject)) {
+func (s *snapshot{{ $snapshotName }}) ForEachObject(handleObject func(cluster string, gvk schema.GroupVersionKind, obj resource.TypedObject)) {
     {{- range $group := $groups }}
     {{ $set_import_prefix := printf "%v_sets" (group_import_name $group) }}
     {{- range $resource := $group.Resources }}
diff --git a/contrib/pkg/snapshot/redact.go b/contrib/pkg/snapshot/redact.go
index 12615f156..58be0012b 100644
--- a/contrib/pkg/snapshot/redact.go
+++ b/contrib/pkg/snapshot/redact.go
@@ -5,12 +5,24 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
+const (
+	redactedString = "<redacted>"
+)
+
 // RedactSecretData returns a copy with sensitive information redacted
 func RedactSecretData(obj client.Object) client.Object {
 	if sec, ok := obj.(*v1.Secret); ok {
 		redacted := sec.DeepCopyObject().(*v1.Secret)
 		for k := range redacted.Data {
-			redacted.Data[k] = []byte("*****")
+			redacted.Data[k] = []byte(redactedString)
+		}
+
+		// Also need to check for kubectl apply, last applied config.
+		// Secret data can be found there as well if that's how the secret is created
+		for key, _ := range redacted.Annotations {
+			if key == v1.LastAppliedConfigAnnotation {
+				redacted.Annotations[key] = redactedString
+			}
 		}
 		return redacted
 	}