mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-04-03 07:18:49 +02:00
* Issue #1075 - Ability to selectively ignore differences to support fuzzy diff comparisons
590 lines
17 KiB
Go
590 lines
17 KiB
Go
package diff
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/ghodss/yaml"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/yudai/gojsondiff/formatter"
|
|
"golang.org/x/crypto/ssh/terminal"
|
|
corev1 "k8s.io/api/core/v1"
|
|
v1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/equality"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
|
|
"github.com/argoproj/argo-cd/errors"
|
|
"github.com/argoproj/argo-cd/test"
|
|
)
|
|
|
|
var (
|
|
formatOpts = formatter.AsciiFormatterConfig{
|
|
Coloring: terminal.IsTerminal(int(os.Stdout.Fd())),
|
|
}
|
|
)
|
|
|
|
func toUnstructured(obj interface{}) (*unstructured.Unstructured, error) {
|
|
uObj, err := runtime.NewTestUnstructuredConverter(equality.Semantic).ToUnstructured(obj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &unstructured.Unstructured{Object: uObj}, nil
|
|
}
|
|
|
|
func mustToUnstructured(obj interface{}) *unstructured.Unstructured {
|
|
un, err := toUnstructured(obj)
|
|
errors.CheckError(err)
|
|
return un
|
|
}
|
|
|
|
func unmarshalFile(path string) *unstructured.Unstructured {
|
|
data, err := ioutil.ReadFile(path)
|
|
errors.CheckError(err)
|
|
var un unstructured.Unstructured
|
|
err = json.Unmarshal(data, &un.Object)
|
|
errors.CheckError(err)
|
|
return &un
|
|
}
|
|
|
|
func TestDiff(t *testing.T) {
|
|
leftDep := test.DemoDeployment()
|
|
leftUn := mustToUnstructured(leftDep)
|
|
|
|
diffRes := Diff(leftUn, leftUn, nil)
|
|
assert.False(t, diffRes.Diff.Modified())
|
|
ascii, err := diffRes.ASCIIFormat(leftUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
if ascii != "" {
|
|
log.Println(ascii)
|
|
}
|
|
}
|
|
|
|
func TestDiffWithNils(t *testing.T) {
|
|
dep := test.DemoDeployment()
|
|
resource := mustToUnstructured(dep)
|
|
|
|
diffRes := Diff(nil, resource, nil)
|
|
// NOTE: if live is non-nil, and config is nil, this is not considered difference
|
|
// This "difference" is checked at the comparator.
|
|
assert.False(t, diffRes.Diff.Modified())
|
|
diffRes = TwoWayDiff(nil, resource)
|
|
assert.False(t, diffRes.Diff.Modified())
|
|
|
|
diffRes = Diff(resource, nil, nil)
|
|
assert.True(t, diffRes.Diff.Modified())
|
|
diffRes = TwoWayDiff(resource, nil)
|
|
assert.True(t, diffRes.Diff.Modified())
|
|
}
|
|
|
|
func TestDiffNilFieldInLive(t *testing.T) {
|
|
leftDep := test.DemoDeployment()
|
|
rightDep := leftDep.DeepCopy()
|
|
|
|
leftUn := mustToUnstructured(leftDep)
|
|
rightUn := mustToUnstructured(rightDep)
|
|
err := unstructured.SetNestedField(rightUn.Object, nil, "spec")
|
|
assert.Nil(t, err)
|
|
|
|
diffRes := Diff(leftUn, rightUn, nil)
|
|
assert.True(t, diffRes.Modified)
|
|
}
|
|
|
|
func TestDiffArraySame(t *testing.T) {
|
|
leftDep := test.DemoDeployment()
|
|
rightDep := leftDep.DeepCopy()
|
|
|
|
leftUn := mustToUnstructured(leftDep)
|
|
rightUn := mustToUnstructured(rightDep)
|
|
|
|
left := []*unstructured.Unstructured{leftUn}
|
|
right := []*unstructured.Unstructured{rightUn}
|
|
diffResList, err := DiffArray(left, right, nil)
|
|
assert.Nil(t, err)
|
|
assert.False(t, diffResList.Modified)
|
|
}
|
|
|
|
func TestDiffArrayAdditions(t *testing.T) {
|
|
leftDep := test.DemoDeployment()
|
|
rightDep := leftDep.DeepCopy()
|
|
rightDep.Status.Replicas = 1
|
|
|
|
leftUn := mustToUnstructured(leftDep)
|
|
rightUn := mustToUnstructured(rightDep)
|
|
|
|
left := []*unstructured.Unstructured{leftUn}
|
|
right := []*unstructured.Unstructured{rightUn}
|
|
diffResList, err := DiffArray(left, right, nil)
|
|
assert.Nil(t, err)
|
|
assert.False(t, diffResList.Modified)
|
|
}
|
|
|
|
func TestDiffArrayModification(t *testing.T) {
|
|
leftDep := test.DemoDeployment()
|
|
rightDep := leftDep.DeepCopy()
|
|
ten := int32(10)
|
|
rightDep.Spec.Replicas = &ten
|
|
|
|
leftUn := mustToUnstructured(leftDep)
|
|
rightUn := mustToUnstructured(rightDep)
|
|
|
|
left := []*unstructured.Unstructured{leftUn}
|
|
right := []*unstructured.Unstructured{rightUn}
|
|
diffResList, err := DiffArray(left, right, nil)
|
|
assert.Nil(t, err)
|
|
assert.True(t, diffResList.Modified)
|
|
}
|
|
|
|
// TestThreeWayDiff will perform a diff when there is a kubectl.kubernetes.io/last-applied-configuration
|
|
// present in the live object.
|
|
func TestThreeWayDiff(t *testing.T) {
|
|
// 1. get config and live to be the same. Both have a foo annotation.
|
|
configDep := test.DemoDeployment()
|
|
configDep.ObjectMeta.Namespace = ""
|
|
configDep.Annotations = map[string]string{
|
|
"foo": "bar",
|
|
}
|
|
liveDep := configDep.DeepCopy()
|
|
|
|
// 2. add a extra field to the live. this simulates kubernetes adding default values in the
|
|
// object. We should not consider defaulted values as a difference
|
|
liveDep.SetNamespace("default")
|
|
configUn := mustToUnstructured(configDep)
|
|
liveUn := mustToUnstructured(liveDep)
|
|
res := Diff(configUn, liveUn, nil)
|
|
if !assert.False(t, res.Modified) {
|
|
ascii, err := res.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
|
|
// 3. Add a last-applied-configuration annotation in the live. There should still not be any
|
|
// difference
|
|
configBytes, err := json.Marshal(configDep)
|
|
assert.Nil(t, err)
|
|
liveDep.Annotations[v1.LastAppliedConfigAnnotation] = string(configBytes)
|
|
configUn = mustToUnstructured(configDep)
|
|
liveUn = mustToUnstructured(liveDep)
|
|
res = Diff(configUn, liveUn, nil)
|
|
if !assert.False(t, res.Modified) {
|
|
ascii, err := res.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
|
|
// 4. Remove the foo annotation from config and perform the diff again. We should detect a
|
|
// difference since three-way diff detects the removal of a managed field
|
|
delete(configDep.Annotations, "foo")
|
|
configUn = mustToUnstructured(configDep)
|
|
liveUn = mustToUnstructured(liveDep)
|
|
res = Diff(configUn, liveUn, nil)
|
|
assert.True(t, res.Modified)
|
|
|
|
// 5. Just to prove three way diff incorporates last-applied-configuration, remove the
|
|
// last-applied-configuration annotation from the live object, and redo the diff. This time,
|
|
// the diff will report not modified (because we have no way of knowing what was a defaulted
|
|
// field without this annotation)
|
|
delete(liveDep.Annotations, v1.LastAppliedConfigAnnotation)
|
|
configUn = mustToUnstructured(configDep)
|
|
liveUn = mustToUnstructured(liveDep)
|
|
res = Diff(configUn, liveUn, nil)
|
|
ascii, err := res.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
if ascii != "" {
|
|
log.Println(ascii)
|
|
}
|
|
assert.False(t, res.Modified)
|
|
}
|
|
|
|
var demoConfig = `
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": {
|
|
"labels": {
|
|
"app.kubernetes.io/instance": "argocd-demo"
|
|
},
|
|
"name": "argocd-application-controller"
|
|
}
|
|
}
|
|
`
|
|
|
|
var demoLive = `
|
|
{
|
|
"apiVersion": "v1",
|
|
"kind": "ServiceAccount",
|
|
"metadata": {
|
|
"annotations": {
|
|
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/instance\":\"argocd-demo\"},\"name\":\"argocd-application-controller\",\"namespace\":\"argocd-demo\"}}\n"
|
|
},
|
|
"creationTimestamp": "2018-04-16T22:08:57Z",
|
|
"labels": {
|
|
"app.kubernetes.io/instance": "argocd-demo"
|
|
},
|
|
"name": "argocd-application-controller",
|
|
"namespace": "argocd-demo",
|
|
"resourceVersion": "7584502",
|
|
"selfLink": "/api/v1/namespaces/argocd-demo/serviceaccounts/argocd-application-controller",
|
|
"uid": "c22bb2b4-41c2-11e8-978a-028445d52ec8"
|
|
},
|
|
"secrets": [
|
|
{
|
|
"name": "argocd-application-controller-token-kfxct"
|
|
}
|
|
]
|
|
}
|
|
`
|
|
|
|
// Tests a real world example
|
|
func TestThreeWayDiffExample1(t *testing.T) {
|
|
var configUn, liveUn unstructured.Unstructured
|
|
// NOTE: it is intentional to unmarshal to Unstructured.Object instead of just Unstructured
|
|
// since it catches a case when we comparison fails due to subtle differences in types
|
|
// (e.g. float vs. int)
|
|
err := json.Unmarshal([]byte(demoConfig), &configUn.Object)
|
|
assert.Nil(t, err)
|
|
err = json.Unmarshal([]byte(demoLive), &liveUn.Object)
|
|
assert.Nil(t, err)
|
|
dr := Diff(&configUn, &liveUn, nil)
|
|
assert.False(t, dr.Modified)
|
|
ascii, err := dr.ASCIIFormat(&liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
if ascii != "" {
|
|
log.Println(ascii)
|
|
}
|
|
|
|
}
|
|
|
|
func TestThreeWayDiffExample2(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/elasticsearch-config.json")
|
|
liveUn := unmarshalFile("testdata/elasticsearch-live.json")
|
|
dr := Diff(configUn, liveUn, nil)
|
|
assert.False(t, dr.Modified)
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
|
|
// TestThreeWayDiffExample2WithDifference is same as TestThreeWayDiffExample2 but with differences
|
|
func TestThreeWayDiffExample2WithDifference(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/elasticsearch-config.json")
|
|
liveUn := unmarshalFile("testdata/elasticsearch-live.json")
|
|
labels := configUn.GetLabels()
|
|
// add a new label
|
|
labels["foo"] = "bar"
|
|
// modify a label
|
|
labels["chart"] = "elasticsearch-1.7.1"
|
|
// remove an existing label
|
|
delete(labels, "release")
|
|
configUn.SetLabels(labels)
|
|
|
|
dr := Diff(configUn, liveUn, nil)
|
|
assert.True(t, dr.Modified)
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
|
|
// Check that we indicate missing/extra/changed correctly
|
|
showsMissing := 0
|
|
showsExtra := 0
|
|
showsChanged := 0
|
|
for _, line := range strings.Split(ascii, "\n") {
|
|
if strings.HasPrefix(line, `+ "foo": "bar"`) {
|
|
showsMissing++
|
|
}
|
|
if strings.HasPrefix(line, `- "release": "elasticsearch4"`) {
|
|
showsExtra++
|
|
}
|
|
if strings.HasPrefix(line, `+ "chart": "elasticsearch-1.7.1"`) {
|
|
showsChanged++
|
|
}
|
|
if strings.HasPrefix(line, `- "chart": "elasticsearch-1.7.0"`) {
|
|
showsChanged++
|
|
}
|
|
}
|
|
assert.Equal(t, 1, showsMissing)
|
|
assert.Equal(t, 1, showsExtra)
|
|
assert.Equal(t, 2, showsChanged)
|
|
}
|
|
|
|
func TestThreeWayDiffExplicitNamespace(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/spinnaker-sa-config.json")
|
|
liveUn := unmarshalFile("testdata/spinnaker-sa-live.json")
|
|
dr := Diff(configUn, liveUn, nil)
|
|
assert.False(t, dr.Modified)
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
|
|
func TestRemoveNamespaceAnnotation(t *testing.T) {
|
|
obj := removeNamespaceAnnotation(&unstructured.Unstructured{Object: map[string]interface{}{
|
|
"metadata": map[string]interface{}{
|
|
"name": "test",
|
|
"namespace": "default",
|
|
},
|
|
}})
|
|
assert.Equal(t, "", obj.GetNamespace())
|
|
|
|
obj = removeNamespaceAnnotation(&unstructured.Unstructured{Object: map[string]interface{}{
|
|
"metadata": map[string]interface{}{
|
|
"name": "test",
|
|
"namespace": "default",
|
|
"annotations": make(map[string]interface{}),
|
|
},
|
|
}})
|
|
assert.Equal(t, "", obj.GetNamespace())
|
|
assert.Nil(t, obj.GetAnnotations())
|
|
}
|
|
|
|
const customObjConfig = `
|
|
apiVersion: foo.io/v1
|
|
kind: Foo
|
|
metadata:
|
|
name: my-foo
|
|
namespace: kube-system
|
|
spec:
|
|
foo: bar
|
|
`
|
|
|
|
const customObjLive = `
|
|
apiVersion: foo.io/v1
|
|
kind: Foo
|
|
metadata:
|
|
creationTimestamp: 2018-07-17 09:17:05 UTC
|
|
name: my-foo
|
|
resourceVersion: '10308211'
|
|
selfLink: "/apis/rbac.authorization.k8s.io/v1/clusterroles/argocd-manager-role"
|
|
uid: 2c3d5405-89a2-11e8-aff0-42010a8a0fc6
|
|
spec:
|
|
foo: bar
|
|
`
|
|
|
|
func TestIgnoreNamespaceForClusterScopedResources(t *testing.T) {
|
|
var configUn unstructured.Unstructured
|
|
var liveUn unstructured.Unstructured
|
|
err := yaml.Unmarshal([]byte(customObjLive), &liveUn)
|
|
assert.Nil(t, err)
|
|
err = yaml.Unmarshal([]byte(customObjConfig), &configUn)
|
|
assert.Nil(t, err)
|
|
dr := Diff(&configUn, &liveUn, nil)
|
|
assert.False(t, dr.Modified)
|
|
}
|
|
|
|
const secretConfig = `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: my-secret
|
|
type: Opaque
|
|
stringData:
|
|
foo: bar
|
|
bar: "1234"
|
|
data:
|
|
baz: cXV4
|
|
`
|
|
|
|
const secretLive = `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
creationTimestamp: 2018-11-19T11:30:40Z
|
|
name: my-secret
|
|
namespace: argocd
|
|
resourceVersion: "25848035"
|
|
selfLink: /api/v1/namespaces/argocd/secrets/my-secret
|
|
uid: 8b4a2766-ebee-11e8-93c0-42010a8a0013
|
|
type: Opaque
|
|
data:
|
|
foo: YmFy
|
|
bar: MTIzNA==
|
|
baz: cXV4
|
|
`
|
|
|
|
func TestSecretStringData(t *testing.T) {
|
|
var err error
|
|
var configUn unstructured.Unstructured
|
|
err = yaml.Unmarshal([]byte(secretConfig), &configUn)
|
|
assert.Nil(t, err)
|
|
|
|
var liveUn unstructured.Unstructured
|
|
err = yaml.Unmarshal([]byte(secretLive), &liveUn)
|
|
assert.Nil(t, err)
|
|
|
|
dr := Diff(&configUn, &liveUn, nil)
|
|
if !assert.False(t, dr.Modified) {
|
|
ascii, err := dr.ASCIIFormat(&liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
}
|
|
|
|
// This is invalid because foo is a number, not a string
|
|
const secretInvalidConfig = `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: my-secret
|
|
type: Opaque
|
|
stringData:
|
|
foo: 1234
|
|
`
|
|
|
|
const secretInvalidLive = `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
creationTimestamp: 2018-11-19T11:30:40Z
|
|
name: my-secret
|
|
namespace: argocd
|
|
resourceVersion: "25848035"
|
|
selfLink: /api/v1/namespaces/argocd/secrets/my-secret
|
|
uid: 8b4a2766-ebee-11e8-93c0-42010a8a0013
|
|
type: Opaque
|
|
data:
|
|
foo: MTIzNA==
|
|
`
|
|
|
|
func TestInvalidSecretStringData(t *testing.T) {
|
|
var err error
|
|
var configUn unstructured.Unstructured
|
|
err = yaml.Unmarshal([]byte(secretInvalidConfig), &configUn)
|
|
assert.Nil(t, err)
|
|
|
|
var liveUn unstructured.Unstructured
|
|
err = yaml.Unmarshal([]byte(secretInvalidLive), &liveUn)
|
|
assert.Nil(t, err)
|
|
|
|
dr := Diff(&configUn, nil, nil)
|
|
assert.True(t, dr.Modified)
|
|
}
|
|
|
|
func TestNullSecretData(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/wordpress-config.json")
|
|
liveUn := unmarshalFile("testdata/wordpress-live.json")
|
|
dr := Diff(configUn, liveUn, nil)
|
|
if !assert.False(t, dr.Modified) {
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
}
|
|
|
|
// TestRedactedSecretData tests we are able to perform diff on redacted secret data, which has
|
|
// invalid characters (*) for the the data byte array field.
|
|
func TestRedactedSecretData(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/wordpress-config.json")
|
|
liveUn := unmarshalFile("testdata/wordpress-live.json")
|
|
configData := configUn.Object["data"].(map[string]interface{})
|
|
liveData := liveUn.Object["data"].(map[string]interface{})
|
|
configData["wordpress-password"] = "***"
|
|
configData["smtp-password"] = "***"
|
|
liveData["wordpress-password"] = "******"
|
|
liveData["smtp-password"] = "******"
|
|
dr := Diff(configUn, liveUn, nil)
|
|
if !assert.True(t, dr.Modified) {
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
}
|
|
|
|
func TestNullRoleRule(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/grafana-clusterrole-config.json")
|
|
liveUn := unmarshalFile("testdata/grafana-clusterrole-live.json")
|
|
dr := Diff(configUn, liveUn, nil)
|
|
if !assert.False(t, dr.Modified) {
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
}
|
|
|
|
func TestNullCreationTimestamp(t *testing.T) {
|
|
configUn := unmarshalFile("testdata/sealedsecret-config.json")
|
|
liveUn := unmarshalFile("testdata/sealedsecret-live.json")
|
|
dr := Diff(configUn, liveUn, nil)
|
|
if !assert.False(t, dr.Modified) {
|
|
ascii, err := dr.ASCIIFormat(liveUn, formatOpts)
|
|
assert.Nil(t, err)
|
|
log.Println(ascii)
|
|
}
|
|
}
|
|
|
|
func createSecret(data map[string]string) *unstructured.Unstructured {
|
|
secret := corev1.Secret{TypeMeta: metav1.TypeMeta{Kind: "Secret"}}
|
|
if data != nil {
|
|
secret.Data = make(map[string][]byte)
|
|
for k, v := range data {
|
|
secret.Data[k] = []byte(v)
|
|
}
|
|
}
|
|
|
|
return mustToUnstructured(&secret)
|
|
}
|
|
|
|
func secretData(obj *unstructured.Unstructured) map[string]interface{} {
|
|
data, _, _ := unstructured.NestedMap(obj.Object, "data")
|
|
return data
|
|
}
|
|
|
|
const (
|
|
replacement1 = "*********"
|
|
replacement2 = "**********"
|
|
replacement3 = "***********"
|
|
)
|
|
|
|
func TestHideSecretDataSameKeysDifferentValues(t *testing.T) {
|
|
target, live, err := HideSecretData(
|
|
createSecret(map[string]string{"key1": "test", "key2": "test"}),
|
|
createSecret(map[string]string{"key1": "test-1", "key2": "test-1"}))
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement1, "key2": replacement1}, secretData(target))
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement2, "key2": replacement2}, secretData(live))
|
|
}
|
|
|
|
func TestHideSecretDataSameKeysSameValues(t *testing.T) {
|
|
target, live, err := HideSecretData(
|
|
createSecret(map[string]string{"key1": "test", "key2": "test"}),
|
|
createSecret(map[string]string{"key1": "test", "key2": "test"}))
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement1, "key2": replacement1}, secretData(target))
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement1, "key2": replacement1}, secretData(live))
|
|
}
|
|
|
|
func TestHideSecretDataDifferentKeysDifferentValues(t *testing.T) {
|
|
target, live, err := HideSecretData(
|
|
createSecret(map[string]string{"key1": "test", "key2": "test"}),
|
|
createSecret(map[string]string{"key2": "test-1", "key3": "test-1"}))
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement1, "key2": replacement1}, secretData(target))
|
|
assert.Equal(t, map[string]interface{}{"key2": replacement2, "key3": replacement1}, secretData(live))
|
|
}
|
|
|
|
func TestHideSecretDataLastAppliedConfig(t *testing.T) {
|
|
lastAppliedSecret := createSecret(map[string]string{"key1": "test1"})
|
|
targetSecret := createSecret(map[string]string{"key1": "test2"})
|
|
liveSecret := createSecret(map[string]string{"key1": "test3"})
|
|
lastAppliedStr, err := json.Marshal(lastAppliedSecret)
|
|
assert.Nil(t, err)
|
|
liveSecret.SetAnnotations(map[string]string{corev1.LastAppliedConfigAnnotation: string(lastAppliedStr)})
|
|
|
|
target, live, err := HideSecretData(targetSecret, liveSecret)
|
|
assert.Nil(t, err)
|
|
err = json.Unmarshal([]byte(live.GetAnnotations()[corev1.LastAppliedConfigAnnotation]), &lastAppliedSecret)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement1}, secretData(target))
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement2}, secretData(live))
|
|
assert.Equal(t, map[string]interface{}{"key1": replacement3}, secretData(lastAppliedSecret))
|
|
|
|
}
|