Skip to content

Commit 0cc4181

Browse files
committed
resource/helm_release: don't drop the release from state when the lookup fails
resourceReleaseExists reports false both when a release is genuinely absent and when the lookup against the cluster failed, telling the two apart only through the returned diagnostics. Read and Delete acted on the boolean before appending those diagnostics, so any transient error was silently swallowed. In Read that means a hiccup while talking to the API server (we hit "net/http: TLS handshake timeout" against AKS, which the kubernetes provider surfaced as an error in the same run) removes the release from state. The following plan turns the refresh into a create, and the create then fails with "cannot re-use a name that is still in use" because the release was there the whole time. Delete has the same problem: it returns early and drops the resource without ever running the uninstall, leaving the release behind in the cluster. Check the diagnostics first in both places, which is what Create already does and what the SDKv2 implementation did before the plugin framework migration.
1 parent a4f1c1d commit 0cc4181

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

helm/resource_helm_release.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,15 +1015,21 @@ func (r *HelmRelease) Read(ctx context.Context, req resource.ReadRequest, resp *
10151015
return
10161016
}
10171017

1018+
// resourceReleaseExists returns false both when the release is genuinely
1019+
// gone and when the lookup itself failed, so the diagnostics have to be
1020+
// checked first. Otherwise a transient error talking to the cluster (for
1021+
// example "net/http: TLS handshake timeout") removes the release from
1022+
// state, and the next apply plans a create that fails with "cannot re-use
1023+
// a name that is still in use".
10181024
exists, diags := resourceReleaseExists(ctx, state.Name.ValueString(), state.Namespace.ValueString(), meta)
1019-
if !exists {
1020-
resp.State.RemoveResource(ctx)
1021-
return
1022-
}
10231025
resp.Diagnostics.Append(diags...)
10241026
if resp.Diagnostics.HasError() {
10251027
return
10261028
}
1029+
if !exists {
1030+
resp.State.RemoveResource(ctx)
1031+
return
1032+
}
10271033

10281034
logID := fmt.Sprintf("[resourceReleaseRead: %s]", state.Name.ValueString())
10291035
tflog.Debug(ctx, fmt.Sprintf("%s Started", logID))
@@ -1251,14 +1257,16 @@ func (r *HelmRelease) Delete(ctx context.Context, req resource.DeleteRequest, re
12511257
name := state.Name.ValueString()
12521258
namespace := state.Namespace.ValueString()
12531259

1260+
// Same as in Read: a failed lookup also reports the release as missing, so
1261+
// bail out on the diagnostics before treating it as already uninstalled.
12541262
exists, diags := resourceReleaseExists(ctx, name, namespace, meta)
1255-
if !exists {
1256-
return
1257-
}
12581263
resp.Diagnostics.Append(diags...)
12591264
if resp.Diagnostics.HasError() {
12601265
return
12611266
}
1267+
if !exists {
1268+
return
1269+
}
12621270

12631271
// Get Helm configuration
12641272
actionConfig, err := meta.GetHelmConfiguration(ctx, namespace)

0 commit comments

Comments
 (0)