github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/utils/createOrUpdate_test.go (about) 1 package utils 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 "github.com/stretchr/testify/require" 8 "gopkg.in/yaml.v3" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 11 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 12 "github.com/argoproj/argo-cd/v3/util/argo/normalizers" 13 ) 14 15 func Test_applyIgnoreDifferences(t *testing.T) { 16 t.Parallel() 17 18 appMeta := metav1.TypeMeta{ 19 APIVersion: v1alpha1.ApplicationSchemaGroupVersionKind.GroupVersion().String(), 20 Kind: v1alpha1.ApplicationSchemaGroupVersionKind.Kind, 21 } 22 testCases := []struct { 23 name string 24 ignoreDifferences v1alpha1.ApplicationSetIgnoreDifferences 25 foundApp string 26 generatedApp string 27 expectedApp string 28 }{ 29 { 30 name: "empty ignoreDifferences", 31 foundApp: ` 32 spec: {}`, 33 generatedApp: ` 34 spec: {}`, 35 expectedApp: ` 36 spec: {}`, 37 }, 38 { 39 // For this use case: https://github.com/argoproj/argo-cd/issues/9101#issuecomment-1191138278 40 name: "ignore target revision with jq", 41 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 42 {JQPathExpressions: []string{".spec.source.targetRevision"}}, 43 }, 44 foundApp: ` 45 spec: 46 source: 47 targetRevision: foo`, 48 generatedApp: ` 49 spec: 50 source: 51 targetRevision: bar`, 52 expectedApp: ` 53 spec: 54 source: 55 targetRevision: foo`, 56 }, 57 { 58 // For this use case: https://github.com/argoproj/argo-cd/issues/9101#issuecomment-1103593714 59 name: "ignore helm parameter with jq", 60 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 61 {JQPathExpressions: []string{`.spec.source.helm.parameters | select(.name == "image.tag")`}}, 62 }, 63 foundApp: ` 64 spec: 65 source: 66 helm: 67 parameters: 68 - name: image.tag 69 value: test 70 - name: another 71 value: value`, 72 generatedApp: ` 73 spec: 74 source: 75 helm: 76 parameters: 77 - name: image.tag 78 value: v1.0.0 79 - name: another 80 value: value`, 81 expectedApp: ` 82 spec: 83 source: 84 helm: 85 parameters: 86 - name: image.tag 87 value: test 88 - name: another 89 value: value`, 90 }, 91 { 92 // For this use case: https://github.com/argoproj/argo-cd/issues/9101#issuecomment-1191138278 93 name: "ignore auto-sync in appset when it's not in the cluster with jq", 94 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 95 {JQPathExpressions: []string{".spec.syncPolicy.automated"}}, 96 }, 97 foundApp: ` 98 spec: 99 syncPolicy: 100 retry: 101 limit: 5`, 102 generatedApp: ` 103 spec: 104 syncPolicy: 105 automated: 106 selfHeal: true 107 retry: 108 limit: 5`, 109 expectedApp: ` 110 spec: 111 syncPolicy: 112 retry: 113 limit: 5`, 114 }, 115 { 116 name: "ignore auto-sync in the cluster when it's not in the appset with jq", 117 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 118 {JQPathExpressions: []string{".spec.syncPolicy.automated"}}, 119 }, 120 foundApp: ` 121 spec: 122 syncPolicy: 123 automated: 124 selfHeal: true 125 retry: 126 limit: 5`, 127 generatedApp: ` 128 spec: 129 syncPolicy: 130 retry: 131 limit: 5`, 132 expectedApp: ` 133 spec: 134 syncPolicy: 135 automated: 136 selfHeal: true 137 retry: 138 limit: 5`, 139 }, 140 { 141 // For this use case: https://github.com/argoproj/argo-cd/issues/9101#issuecomment-1420656537 142 name: "ignore a one-off annotation with jq", 143 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 144 {JQPathExpressions: []string{`.metadata.annotations | select(.["foo.bar"] == "baz")`}}, 145 }, 146 foundApp: ` 147 metadata: 148 annotations: 149 foo.bar: baz 150 some.other: annotation`, 151 generatedApp: ` 152 metadata: 153 annotations: 154 some.other: annotation`, 155 expectedApp: ` 156 metadata: 157 annotations: 158 foo.bar: baz 159 some.other: annotation`, 160 }, 161 { 162 // For this use case: https://github.com/argoproj/argo-cd/issues/9101#issuecomment-1515672638 163 name: "ignore the source.plugin field with a json pointer", 164 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 165 {JSONPointers: []string{"/spec/source/plugin"}}, 166 }, 167 foundApp: ` 168 spec: 169 source: 170 plugin: 171 parameters: 172 - name: url 173 string: https://example.com`, 174 generatedApp: ` 175 spec: 176 source: 177 plugin: 178 parameters: 179 - name: url 180 string: https://example.com/wrong`, 181 expectedApp: ` 182 spec: 183 source: 184 plugin: 185 parameters: 186 - name: url 187 string: https://example.com`, 188 }, 189 { 190 // For this use case: https://github.com/argoproj/argo-cd/pull/14743#issuecomment-1761954799 191 name: "ignore parameters added to a multi-source app in the cluster", 192 ignoreDifferences: v1alpha1.ApplicationSetIgnoreDifferences{ 193 {JQPathExpressions: []string{`.spec.sources[] | select(.repoURL | contains("test-repo")).helm.parameters`}}, 194 }, 195 foundApp: ` 196 spec: 197 sources: 198 - repoURL: https://git.example.com/test-org/test-repo 199 helm: 200 parameters: 201 - name: test 202 value: hi`, 203 generatedApp: ` 204 spec: 205 sources: 206 - repoURL: https://git.example.com/test-org/test-repo`, 207 expectedApp: ` 208 spec: 209 sources: 210 - repoURL: https://git.example.com/test-org/test-repo 211 helm: 212 parameters: 213 - name: test 214 value: hi`, 215 }, 216 } 217 218 for _, tc := range testCases { 219 tc := tc 220 t.Run(tc.name, func(t *testing.T) { 221 t.Parallel() 222 foundApp := v1alpha1.Application{TypeMeta: appMeta} 223 err := yaml.Unmarshal([]byte(tc.foundApp), &foundApp) 224 require.NoError(t, err, tc.foundApp) 225 generatedApp := v1alpha1.Application{TypeMeta: appMeta} 226 err = yaml.Unmarshal([]byte(tc.generatedApp), &generatedApp) 227 require.NoError(t, err, tc.generatedApp) 228 err = applyIgnoreDifferences(tc.ignoreDifferences, &foundApp, &generatedApp, normalizers.IgnoreNormalizerOpts{}) 229 require.NoError(t, err) 230 yamlFound, err := yaml.Marshal(tc.foundApp) 231 require.NoError(t, err) 232 yamlExpected, err := yaml.Marshal(tc.expectedApp) 233 require.NoError(t, err) 234 assert.YAMLEq(t, string(yamlExpected), string(yamlFound)) 235 }) 236 } 237 }