diff --git a/argocd/resource_argocd_application.go b/argocd/resource_argocd_application.go index d14e91d0..31569ab0 100644 --- a/argocd/resource_argocd_application.go +++ b/argocd/resource_argocd_application.go @@ -89,7 +89,7 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData } } c := *server.ApplicationClient - app, err := c.Get(ctx, &applicationClient.ApplicationQuery{ + apps, err := c.List(ctx, &applicationClient.ApplicationQuery{ Name: &objectMeta.Name, AppNamespace: &objectMeta.Namespace, }) @@ -102,12 +102,22 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData }, } } - if app != nil { - switch app.DeletionTimestamp { + if apps != nil { + if len(apps.Items) != 1 { + return []diag.Diagnostic{ + { + Severity: diag.Error, + Summary: fmt.Sprintf("found multiple applications matching name '%s' and namespace '%s'", objectMeta.Name, objectMeta.Namespace), + Detail: err.Error(), + }, + } + } + + switch apps.Items[0].DeletionTimestamp { case nil: default: // Pre-existing app is still in Kubernetes soft deletion queue - time.Sleep(time.Duration(*app.DeletionGracePeriodSeconds)) + time.Sleep(time.Duration(*apps.Items[0].DeletionGracePeriodSeconds)) } } @@ -190,7 +200,7 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData } } - app, err = c.Create(ctx, &applicationClient.ApplicationCreateRequest{ + app, err := c.Create(ctx, &applicationClient.ApplicationCreateRequest{ Application: &application.Application{ ObjectMeta: objectMeta, Spec: spec, @@ -222,18 +232,21 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData if wait, ok := d.GetOk("wait"); ok && wait.(bool) { err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { - a, err := c.Get(ctx, &applicationClient.ApplicationQuery{ + list, err := c.List(ctx, &applicationClient.ApplicationQuery{ Name: &app.Name, AppNamespace: &app.Namespace, }) if err != nil { return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", app.Name, err)) } - if a.Status.Health.Status != health.HealthStatusHealthy { - return resource.RetryableError(fmt.Errorf("expected application health status to be healthy but was %s", a.Status.Health.Status)) + if len(list.Items) != 1 { + return resource.NonRetryableError(fmt.Errorf("found multiple applications matching name '%s' and namespace '%s'", app.Name, app.Namespace)) + } + if list.Items[0].Status.Health.Status != health.HealthStatusHealthy { + return resource.RetryableError(fmt.Errorf("expected application health status to be healthy but was %s", list.Items[0].Status.Health.Status)) } - if a.Status.Sync.Status != application.SyncStatusCodeSynced { - return resource.RetryableError(fmt.Errorf("expected application sync status to be synced but was %s", a.Status.Sync.Status)) + if list.Items[0].Status.Sync.Status != application.SyncStatusCodeSynced { + return resource.RetryableError(fmt.Errorf("expected application sync status to be synced but was %s", list.Items[0].Status.Sync.Status)) } return nil }) @@ -268,7 +281,7 @@ func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData, appName := ids[0] namespace := ids[1] - app, err := c.Get(ctx, &applicationClient.ApplicationQuery{ + apps, err := c.List(ctx, &applicationClient.ApplicationQuery{ Name: &appName, AppNamespace: &namespace, }) @@ -285,7 +298,16 @@ func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData, }, } } - err = flattenApplication(app, d) + if len(apps.Items) != 1 { + return []diag.Diagnostic{ + { + Severity: diag.Error, + Summary: fmt.Sprintf("found multiple applications matching name '%s' and namespace '%s'", appName, namespace), + Detail: err.Error(), + }, + } + } + err = flattenApplication(&apps.Items[0], d) if err != nil { return []diag.Diagnostic{ { @@ -407,11 +429,11 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData } } } - app, err := c.Get(ctx, &applicationClient.ApplicationQuery{ + apps, err := c.List(ctx, &applicationClient.ApplicationQuery{ Name: &appName, AppNamespace: &namespace, }) - if app != nil { + if apps != nil { // Kubernetes API requires providing the up-to-date correct ResourceVersion for updates // FIXME ResourceVersion not available anymore // appRequest.ResourceVersion = app.ResourceVersion @@ -428,18 +450,21 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData } if wait, _ok := d.GetOk("wait"); _ok && wait.(bool) { err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { - a, err := c.Get(ctx, &applicationClient.ApplicationQuery{ - Name: &app.Name, - AppNamespace: &app.Namespace, + list, err := c.List(ctx, &applicationClient.ApplicationQuery{ + Name: &appName, + AppNamespace: &namespace, }) if err != nil { - return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", app.Name, err)) + return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", list.Items[0].Name, err)) + } + if len(list.Items) != 1 { + return resource.NonRetryableError(fmt.Errorf("found multiple applications matching name '%s' and namespace '%s'", appName, namespace)) } - if a.Status.Health.Status != health.HealthStatusHealthy { - return resource.RetryableError(fmt.Errorf("expected application health status to be healthy but was %s", a.Status.Health.Status)) + if list.Items[0].Status.Health.Status != health.HealthStatusHealthy { + return resource.RetryableError(fmt.Errorf("expected application health status to be healthy but was %s", list.Items[0].Status.Health.Status)) } - if a.Status.Sync.Status != application.SyncStatusCodeSynced { - return resource.RetryableError(fmt.Errorf("expected application sync status to be synced but was %s", a.Status.Sync.Status)) + if list.Items[0].Status.Sync.Status != application.SyncStatusCodeSynced { + return resource.RetryableError(fmt.Errorf("expected application sync status to be synced but was %s", list.Items[0].Status.Sync.Status)) } return nil }) @@ -489,7 +514,7 @@ func resourceArgoCDApplicationDelete(ctx context.Context, d *schema.ResourceData } if wait, ok := d.GetOk("wait"); ok && wait.(bool) { err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { - _, err := c.Get(ctx, &applicationClient.ApplicationQuery{ + _, err := c.List(ctx, &applicationClient.ApplicationQuery{ Name: &appName, AppNamespace: &namespace, })