Skip to content

Commit

Permalink
Fix deletion not found handling and add related tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JaylonmcShan03 committed Sep 25, 2024
1 parent 9d6074c commit 0a5f1ea
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 9 deletions.
27 changes: 18 additions & 9 deletions manifest/provider/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,16 +540,25 @@ func (s *RawProviderServer) ApplyResourceChange(ctx context.Context, req *tfprot

err = rs.Delete(ctxDeadline, rname, metav1.DeleteOptions{})
if err != nil {
rn := types.NamespacedName{Namespace: rnamespace, Name: rname}.String()
resp.Diagnostics = append(resp.Diagnostics,
&tfprotov5.Diagnostic{
Severity: tfprotov5.DiagnosticSeverityError,
Summary: fmt.Sprintf("Error deleting resource %s: %s", rn, err),
Detail: err.Error(),
})
return resp, nil
}
if apierrors.IsNotFound(err) {
s.logger.Trace("[ApplyResourceChange][Delete]", "Resource is already deleted")

resp.Diagnostics = append(resp.Diagnostics,
&tfprotov5.Diagnostic{
Severity: tfprotov5.DiagnosticSeverityWarning,
Summary: fmt.Sprintf("Resource %q was already deleted", rname),
Detail: fmt.Sprintf("The resource %q was not found in the Kubernetes API. This may be due to the resource being already deleted.", rname),
})
} else {
resp.Diagnostics = append(resp.Diagnostics,
&tfprotov5.Diagnostic{
Severity: tfprotov5.DiagnosticSeverityError,
Summary: fmt.Sprintf("Error deleting resource %s: %s", rname, err),
Detail: err.Error(),
})
return resp, nil
}
}
// wait for delete
for {
if time.Now().After(deadline) {
Expand Down
77 changes: 77 additions & 0 deletions manifest/test/acceptance/delete_not_found_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:build acceptance
// +build acceptance

package acceptance

import (
"context"
"testing"
"time"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/terraform-provider-kubernetes/manifest/provider"
"github.com/hashicorp/terraform-provider-kubernetes/manifest/test/helper/kubernetes"
)

func TestKubernetesManifest_DeletionNotFound(t *testing.T) {
ctx := context.Background()

reattachInfo, err := provider.ServeTest(ctx, hclog.Default(), t)
if err != nil {
t.Fatalf("Failed to create provider instance: %v", err)
}

name := randName()
namespace := randName()

tf := tfhelper.RequireNewWorkingDir(ctx, t)
tf.SetReattachInfo(ctx, reattachInfo)

k8shelper.CreateNamespace(t, namespace)
t.Logf("Verifying if namespace %s exists", namespace)
k8shelper.AssertResourceExists(t, "v1", "namespaces", namespace)

defer func() {
tf.Destroy(ctx)
tf.Close()
k8shelper.DeleteResource(t, namespace, kubernetes.NewGroupVersionResource("v1", "namespaces"))
k8shelper.AssertResourceDoesNotExist(t, "v1", "namespaces", namespace)
}()

tfvars := TFVARS{
"namespace": namespace,
"name": name,
}

// Load the Terraform config that will create the ConfigMap
tfconfig := loadTerraformConfig(t, "DeleteNotFoundTest/resource.tf", tfvars)
tf.SetConfig(ctx, tfconfig)

t.Log("Applying Terraform configuration to create ConfigMap")
if err := tf.Apply(ctx); err != nil {
t.Fatalf("Terraform apply failed: %v", err)
}

state, err := tf.State(ctx)
if err != nil {
t.Fatalf("Failed to retrieve Terraform state: %v", err)
}
t.Logf("Terraform state: %v", state)

time.Sleep(2 * time.Second)

t.Logf("Checking if ConfigMap %s in namespace %s was created", name, namespace)
k8shelper.AssertNamespacedResourceExists(t, "v1", "configmaps", namespace, name)

// Simulating the deletion of the resource outside of Terraform
k8shelper.DeleteNamespacedResource(t, name, namespace, kubernetes.NewGroupVersionResource("v1", "configmaps"))

// Running tf destroy in order to check if we are handling "404 Not Found" gracefully
tf.Destroy(ctx)

// Ensuring that the ConfigMap no longer exists
k8shelper.AssertNamespacedResourceDoesNotExist(t, "v1", "configmaps", namespace, name)
}
14 changes: 14 additions & 0 deletions manifest/test/acceptance/testdata/DeleteNotFoundTest/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "kubernetes_manifest" "test" {
manifest = {
"apiVersion" = "v1"
"kind" = "ConfigMap"
"metadata" = {
"name" = var.name
"namespace" = var.namespace
}
"data" = {
"foo" = "bar"
}
}
}

19 changes: 19 additions & 0 deletions manifest/test/acceptance/testdata/DeleteNotFoundTest/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

# These variable declarations are only used for interactive testing.
# The test code will template in different variable declarations with a default value when running the test.
#
# To set values for interactive runs, create a var-file and set values in it.
# If the name of the var-file ends in '.auto.tfvars' (e.g. myvalues.auto.tfvars)
# it will be automatically picked up and used by Terraform.
#
# DO NOT check in any files named *.auto.tfvars when making changes to tests.

variable "name" {
type = string
}

variable "namespace" {
type = string
}

0 comments on commit 0a5f1ea

Please sign in to comment.