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