github.com/argoproj/argo-cd/v2@v2.10.5/test/e2e/kustomize_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"strconv"
     5  	"testing"
     6  
     7  	"github.com/argoproj/gitops-engine/pkg/health"
     8  	. "github.com/argoproj/gitops-engine/pkg/sync/common"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	. "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
    12  	"github.com/argoproj/argo-cd/v2/test/e2e/fixture"
    13  	. "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
    14  	"github.com/argoproj/argo-cd/v2/util/errors"
    15  )
    16  
    17  func TestKustomize2AppSource(t *testing.T) {
    18  
    19  	patchLabelMatchesFor := func(kind string) func(app *Application) {
    20  		return func(app *Application) {
    21  			name := "k2-patched-guestbook-ui-deploy1"
    22  			labelValue, err := fixture.Run(
    23  				"", "kubectl", "-n="+fixture.DeploymentNamespace(),
    24  				"get", kind, name,
    25  				"-ojsonpath={.metadata.labels.patched-by}")
    26  			assert.NoError(t, err)
    27  			assert.Equal(t, "argo-cd", labelValue, "wrong value of 'patched-by' label of %s %s", kind, name)
    28  		}
    29  	}
    30  
    31  	Given(t).
    32  		Path(guestbookPath).
    33  		NamePrefix("k2-").
    34  		NameSuffix("-deploy1").
    35  		When().
    36  		CreateApp().
    37  		Then().
    38  		Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
    39  		When().
    40  		PatchApp(`[
    41  			{
    42  				"op": "replace",
    43  				"path": "/spec/source/kustomize/namePrefix",
    44  				"value": "k2-patched-"
    45  			},
    46  			{
    47  				"op": "add",
    48  				"path": "/spec/source/kustomize/commonLabels",
    49  				"value": {
    50  					"patched-by": "argo-cd"
    51  				}
    52  			}
    53  		]`).
    54  		Then().
    55  		Expect(Success("")).
    56  		When().
    57  		Sync().
    58  		Then().
    59  		Expect(Success("")).
    60  		Expect(OperationPhaseIs(OperationSucceeded)).
    61  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
    62  		Expect(HealthIs(health.HealthStatusHealthy)).
    63  		And(patchLabelMatchesFor("Service")).
    64  		And(patchLabelMatchesFor("Deployment"))
    65  }
    66  
    67  // when we have a config map generator, AND the ignore annotation, it is ignored in the app's sync status
    68  func TestSyncStatusOptionIgnore(t *testing.T) {
    69  	var oldMap string
    70  	Given(t).
    71  		Path("kustomize-cm-gen").
    72  		When().
    73  		CreateApp().
    74  		Sync().
    75  		Then().
    76  		Expect(OperationPhaseIs(OperationSucceeded)).
    77  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
    78  		Expect(HealthIs(health.HealthStatusHealthy)).
    79  		And(func(app *Application) {
    80  			resourceStatus := app.Status.Resources[0]
    81  			assert.Contains(t, resourceStatus.Name, "my-map-")
    82  			assert.Equal(t, SyncStatusCodeSynced, resourceStatus.Status)
    83  
    84  			oldMap = resourceStatus.Name
    85  		}).
    86  		When().
    87  		// we now force generation of a second CM
    88  		PatchFile("kustomization.yaml", `[{"op": "replace", "path": "/configMapGenerator/0/literals/0", "value": "foo=baz"}]`).
    89  		Refresh(RefreshTypeHard).
    90  		Then().
    91  		// this is standard logging from the command - tough one - true statement
    92  		When().
    93  		Sync().
    94  		Then().
    95  		Expect(OperationPhaseIs(OperationSucceeded)).
    96  		// this is a key check - we expect the app to be healthy because, even though we have a resources that needs
    97  		// pruning, because it is annotated with IgnoreExtraneous it should not contribute to the sync status
    98  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
    99  		Expect(HealthIs(health.HealthStatusHealthy)).
   100  		And(func(app *Application) {
   101  			assert.Equal(t, 2, len(app.Status.Resources))
   102  			for _, resourceStatus := range app.Status.Resources {
   103  				// new map in-sync
   104  				if resourceStatus.Name != oldMap {
   105  					assert.Contains(t, resourceStatus.Name, "my-map-")
   106  					// make sure we've a new map with changed name
   107  					assert.Equal(t, SyncStatusCodeSynced, resourceStatus.Status)
   108  
   109  				} else {
   110  					assert.Equal(t, SyncStatusCodeOutOfSync, resourceStatus.Status)
   111  				}
   112  			}
   113  		})
   114  }
   115  
   116  // make sure we can create an app which has a SSH remote base
   117  func TestKustomizeSSHRemoteBase(t *testing.T) {
   118  	Given(t).
   119  		// not the best test, as we should have two remote repos both with the same SSH private key
   120  		SSHInsecureRepoURLAdded(true).
   121  		RepoURLType(fixture.RepoURLTypeSSH).
   122  		Path(fixture.LocalOrRemotePath("ssh-kustomize-base")).
   123  		When().
   124  		CreateApp().
   125  		Sync().
   126  		Then().
   127  		Expect(OperationPhaseIs(OperationSucceeded)).
   128  		Expect(ResourceSyncStatusIs("ConfigMap", "my-map", SyncStatusCodeSynced))
   129  }
   130  
   131  // make sure we can create an app which has a SSH remote base
   132  func TestKustomizeDeclarativeInvalidApp(t *testing.T) {
   133  	Given(t).
   134  		Path("invalid-kustomize").
   135  		When().
   136  		Declarative("declarative-apps/app.yaml").
   137  		Then().
   138  		Expect(Success("")).
   139  		Expect(HealthIs(health.HealthStatusHealthy)).
   140  		Expect(SyncStatusIs(SyncStatusCodeUnknown)).
   141  		Expect(Condition(ApplicationConditionComparisonError, "invalid-kustomize/does-not-exist.yaml: no such file or directory"))
   142  }
   143  
   144  // Flag --load_restrictor is no longer supported in Kustomize 4
   145  func TestKustomizeBuildOptionsLoadRestrictor(t *testing.T) {
   146  	Given(t).
   147  		Path(guestbookPath).
   148  		And(func() {
   149  			errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm",
   150  				"-n", fixture.TestNamespace(),
   151  				"-p", `{ "data": { "kustomize.buildOptions": "--load-restrictor LoadRestrictionsNone" } }`))
   152  		}).
   153  		When().
   154  		PatchFile("kustomization.yaml", `[{"op": "replace", "path": "/resources/1", "value": "../guestbook_local/guestbook-ui-svc.yaml"}]`).
   155  		CreateApp().
   156  		Sync().
   157  		Then().
   158  		Expect(OperationPhaseIs(OperationSucceeded)).
   159  		Expect(HealthIs(health.HealthStatusHealthy)).
   160  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   161  		Given().
   162  		And(func() {
   163  			errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm",
   164  				"-n", fixture.TestNamespace(),
   165  				"-p", `{ "data": { "kustomize.buildOptions": "" } }`))
   166  		})
   167  }
   168  
   169  // make sure we we can invoke the CLI to replace images
   170  func TestKustomizeImages(t *testing.T) {
   171  	Given(t).
   172  		Path("kustomize").
   173  		When().
   174  		CreateApp().
   175  		// pass two flags to check the multi flag logic works
   176  		AppSet("--kustomize-image", "alpine:foo", "--kustomize-image", "alpine:bar").
   177  		Then().
   178  		And(func(app *Application) {
   179  			assert.Contains(t, app.Spec.GetSource().Kustomize.Images, KustomizeImage("alpine:bar"))
   180  		})
   181  }
   182  
   183  // make sure we we can invoke the CLI to replace replicas and actual deployment is set to correct value
   184  func TestKustomizeReplicas2AppSource(t *testing.T) {
   185  	deploymentName := "guestbook-ui"
   186  	deploymentReplicas := 2
   187  	checkReplicasFor := func(kind string) func(app *Application) {
   188  		return func(app *Application) {
   189  			name := deploymentName
   190  			replicas, err := fixture.Run(
   191  				"", "kubectl", "-n="+fixture.DeploymentNamespace(),
   192  				"get", kind, name,
   193  				"-ojsonpath={.spec.replicas}")
   194  			assert.NoError(t, err)
   195  			assert.Equal(t, strconv.Itoa(deploymentReplicas), replicas, "wrong value of replicas %s %s", kind, name)
   196  		}
   197  	}
   198  
   199  	Given(t).
   200  		Path("guestbook").
   201  		When().
   202  		CreateApp().
   203  		AppSet("--kustomize-replica", deploymentName+"=2").
   204  		Then().
   205  		And(func(app *Application) {
   206  			assert.Equal(t, deploymentName, app.Spec.Source.Kustomize.Replicas[0].Name)
   207  		}).
   208  		And(func(app *Application) {
   209  			assert.Equal(t, deploymentReplicas, int(app.Spec.Source.Kustomize.Replicas[0].Count.IntVal))
   210  		}). // check Kustomize CLI
   211  		Expect(Success("")).
   212  		When().
   213  		Sync().
   214  		Then().
   215  		Expect(Success("")).
   216  		Expect(OperationPhaseIs(OperationSucceeded)).
   217  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   218  		Expect(HealthIs(health.HealthStatusHealthy)).
   219  		And(checkReplicasFor("Deployment"))
   220  }
   221  
   222  // make sure we we can invoke the CLI to set namesuffix
   223  func TestKustomizeNameSuffix(t *testing.T) {
   224  	Given(t).
   225  		Path("kustomize").
   226  		When().
   227  		CreateApp().
   228  		AppSet("--namesuffix", "-suf").
   229  		Then().
   230  		And(func(app *Application) {
   231  			assert.Contains(t, app.Spec.GetSource().Kustomize.NameSuffix, "-suf")
   232  		})
   233  }
   234  
   235  // make sure we we can invoke the CLI to set and unset namesuffix and kustomize-image
   236  func TestKustomizeUnsetOverride(t *testing.T) {
   237  	Given(t).
   238  		Path("kustomize").
   239  		When().
   240  		CreateApp().
   241  		AppSet("--namesuffix", "-suf").
   242  		Then().
   243  		And(func(app *Application) {
   244  			assert.Contains(t, app.Spec.GetSource().Kustomize.NameSuffix, "-suf")
   245  		}).
   246  		When().
   247  		AppUnSet("--namesuffix").
   248  		Then().
   249  		And(func(app *Application) {
   250  			assert.Nil(t, app.Spec.GetSource().Kustomize)
   251  		}).
   252  		When().
   253  		AppSet("--kustomize-image", "alpine:foo", "--kustomize-image", "alpine:bar").
   254  		Then().
   255  		And(func(app *Application) {
   256  			assert.Contains(t, app.Spec.GetSource().Kustomize.Images, KustomizeImage("alpine:bar"))
   257  		}).
   258  		When().
   259  		//AppUnSet("--kustomize-image=alpine").
   260  		AppUnSet("--kustomize-image", "alpine", "--kustomize-image", "alpine").
   261  		Then().
   262  		And(func(app *Application) {
   263  			assert.Nil(t, app.Spec.GetSource().Kustomize)
   264  		})
   265  }
   266  
   267  // make sure we we can invoke the CLI to set and unset Deployment
   268  func TestKustomizeUnsetOverrideDeployment(t *testing.T) {
   269  	deploymentName := "guestbook-ui"
   270  	deploymentReplicas := int32(2)
   271  	Given(t).
   272  		Path("guestbook").
   273  		When(). // Replicas
   274  		CreateApp().
   275  		AppSet("--kustomize-replica", deploymentName+"=2").
   276  		Then().
   277  		And(func(app *Application) {
   278  			assert.Equal(t, deploymentName, app.Spec.Source.Kustomize.Replicas[0].Name)
   279  		}).
   280  		And(func(app *Application) {
   281  			assert.Equal(t, deploymentReplicas, app.Spec.Source.Kustomize.Replicas[0].Count.IntVal)
   282  		}).
   283  		When().
   284  		AppUnSet("--kustomize-replica", deploymentName).
   285  		Then().
   286  		And(func(app *Application) {
   287  			assert.Nil(t, app.Spec.Source.Kustomize)
   288  		})
   289  }