Skip to content

Commit

Permalink
fix: use List instead of Get to determine existence of application
Browse files Browse the repository at this point in the history
Works around breaking change made to `Get` in order to resolve GHSA-2q5c-qw9c-fmvq. 

See also argoproj/argo-cd#13000
  • Loading branch information
onematchfox committed Mar 29, 2023
1 parent b303f04 commit 4b8e15f
Showing 1 changed file with 48 additions and 23 deletions.
71 changes: 48 additions & 23 deletions argocd/resource_argocd_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
Expand All @@ -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))
}
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
})
Expand Down Expand Up @@ -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,
})
Expand All @@ -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{
{
Expand Down Expand Up @@ -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
Expand All @@ -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
})
Expand Down Expand Up @@ -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,
})
Expand Down

0 comments on commit 4b8e15f

Please sign in to comment.