Skip to content

Commit

Permalink
improve test case for the destroy case
Browse files Browse the repository at this point in the history
  • Loading branch information
chanwit committed Dec 29, 2021
1 parent deb56ae commit c1387cd
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ testbin/*
DESIGN.md
controllers/data/terraform-hello-env/
controllers/data/terraform-hello-world-example/
controllers/data/tf-k8s-configmap/
controllers/data/terratest-master.tar.gz

/config/crd/bases/buckets.yaml
/config/crd/bases/gitrepositories.yaml
/config/release/
Expand Down
Binary file added controllers/data/tf-k8s-configmap.tar.gz
Binary file not shown.
4 changes: 4 additions & 0 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func TestMain(m *testing.M) {
server.RouteToHandler("GET", "/env.tar.gz", func(writer http.ResponseWriter, request *http.Request) {
http.ServeFile(writer, request, "data/terraform-hello-env.tar.gz")
})
server.RouteToHandler("GET", "/tf-k8s-configmap.tar.gz", func(writer http.ResponseWriter, request *http.Request) {
http.ServeFile(writer, request, "data/tf-k8s-configmap.tar.gz")
})

server.Start()

// "preparing flux-system namespace"
Expand Down
49 changes: 41 additions & 8 deletions controllers/tc000130_destroy_no_outputs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
// +kubebuilder:docs-gen:collapse=Imports

func Test_0000130_destroy_no_outputs_test(t *testing.T) {
spec("Terraform object with no backend, with auto approve, will be reconciled to have available outputs.")
spec("Terraform object with no backend, auto approve, will be reconciled to have available outputs.")

// when("creating a Terraform object with the auto approve mode, and having a GitRepository attached to it.")
it("should obtain the TF program's blob from the Source, unpack it, plan it, and apply it correctly with an output available, and there must be *NO* tfstate Secret because no backend specified.")
Expand Down Expand Up @@ -63,12 +63,12 @@ func Test_0000130_destroy_no_outputs_test(t *testing.T) {
Message: "Fetched revision: master/b8e362c206e3d0cbb7ed22ced771a0056455a2fb",
},
},
URL: server.URL() + "/file.tar.gz",
URL: server.URL() + "/tf-k8s-configmap.tar.gz",
Artifact: &sourcev1.Artifact{
Path: "gitrepository/flux-system/test-tf-controller/b8e362c206e3d0cbb7ed22ced771a0056455a2fb.tar.gz",
URL: server.URL() + "/file.tar.gz",
URL: server.URL() + "/tf-k8s-configmap.tar.gz",
Revision: "master/b8e362c206e3d0cbb7ed22ced771a0056455a2fb",
Checksum: "80ddfd18eb96f7d31cadc1a8a5171c6e2d95df3f6c23b0ed9cd8dddf6dba1406", // must be the real checksum value
Checksum: "c3bf30bad9621b5110a3761a70754170d1dae6c525a63098b6ec9919efac3555", // must be the real checksum value
LastUpdateTime: metav1.Time{Time: updatedTime},
},
}
Expand All @@ -79,6 +79,9 @@ func Test_0000130_destroy_no_outputs_test(t *testing.T) {
// createdRepo := sourcev1.GitRepository{}
// g.Expect(k8sClient.Get(ctx, gitRepoKey, &createdRepo)).Should(Succeed())

testEnvKubeConfigPath, err := findKubeConfig(testEnv)
g.Expect(err).Should(BeNil())

given("a Terraform object with auto approve, and attaching it to the GitRepository object")
by("creating a new TF resource and attaching to the repo via sourceRef")
helloWorldTF := infrav1.Terraform{
Expand All @@ -87,14 +90,24 @@ func Test_0000130_destroy_no_outputs_test(t *testing.T) {
Namespace: "flux-system",
},
Spec: infrav1.TerraformSpec{
BackendConfig: &infrav1.BackendConfigSpec{
SecretSuffix: terraformName,
InClusterConfig: false,
ConfigPath: testEnvKubeConfigPath,
},
ApprovePlan: "auto",
Destroy: false,
Path: "./terraform-hello-world-example",
Path: "./tf-k8s-configmap",
SourceRef: infrav1.CrossNamespaceSourceReference{
Kind: "GitRepository",
Name: sourceName,
Namespace: "flux-system",
},
Vars: []infrav1.Variable{
{Name: "kubeconfig", Value: testEnvKubeConfigPath},
{Name: "context", Value: "envtest"},
{Name: "config_name", Value: "cm-" + terraformName},
},
},
}
g.Expect(k8sClient.Create(ctx, &helloWorldTF)).Should(Succeed())
Expand Down Expand Up @@ -196,13 +209,13 @@ func Test_0000130_destroy_no_outputs_test(t *testing.T) {
return nil
}
return createdHelloWorldTF.Status.AvailableOutputs
}, timeout, interval).Should(Equal([]string{"hello_world"}))
}, timeout, interval).Should(Equal([]string{"api_host"}))

// We're testing out side Kubernetes
// so we have to disable in-cluster backend
if os.Getenv("DISABLE_TF_K8S_BACKEND") == "1" {
// So we're expecting that there must be no "tfstate-default-${terraformName}" secret
by("checking that we're testing the controller locally, then there should be no secret generated by default")
by("getting the tfstate and we should see it")
tfStateKey := types.NamespacedName{Namespace: "flux-system", Name: "tfstate-default-" + terraformName}
tfStateSecret := corev1.Secret{}
g.Eventually(func() string {
Expand All @@ -211,11 +224,22 @@ func Test_0000130_destroy_no_outputs_test(t *testing.T) {
return err.Error()
}
return tfStateSecret.Name
}, timeout, interval).Should(Equal("secrets \"tfstate-default-helloworld-destroy-no-outputs\" not found"))
}, timeout, interval).Should(Equal("tfstate-default-helloworld-destroy-no-outputs"))
} else {
// TODO there's must be the default tfstate secret
}

cmPayloadKey := types.NamespacedName{Namespace: "default", Name: "cm-" + terraformName}
var cmPayload corev1.ConfigMap
g.Eventually(func() string {
err := k8sClient.Get(ctx, cmPayloadKey, &cmPayload)
if err != nil {
return ""
}
return cmPayload.Name
}, timeout, interval).Should(Equal("cm-" + terraformName))

it("by updating TF object setting destroy=true to trigger the planning")
g.Expect(k8sClient.Get(ctx, helloWorldTFKey, &createdHelloWorldTF)).Should(Succeed())
createdHelloWorldTF.Spec.Destroy = true
g.Expect(k8sClient.Update(ctx, &createdHelloWorldTF)).Should(Succeed())
Expand Down Expand Up @@ -256,4 +280,13 @@ func Test_0000130_destroy_no_outputs_test(t *testing.T) {
}
return false
}, timeout, interval).Should(BeTrue())

g.Eventually(func() bool {
err := k8sClient.Get(ctx, cmPayloadKey, &cmPayload)
if apierrors.IsNotFound(err) {
return true
}
return false
}, timeout, interval).Should(BeTrue())

}
15 changes: 11 additions & 4 deletions controllers/terraform_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ func (r *TerraformReconciler) shouldWriteOutputs(terraform infrav1.Terraform, ou
return false
}

type LocalPrintfer struct {
logger logr.Logger
}

func (l LocalPrintfer) Printf(format string, v ...interface{}) {
l.logger.Info(fmt.Sprintf(format, v...))
}

func (r *TerraformReconciler) reconcile(ctx context.Context, terraform infrav1.Terraform, sourceObj sourcev1.Source) (infrav1.Terraform, error) {

log := logr.FromContext(ctx)
Expand Down Expand Up @@ -352,6 +360,9 @@ terraform {
err.Error(),
), err
}
tf.SetStdout(os.Stdout)
tf.SetStderr(os.Stderr)
tf.SetLogger(&LocalPrintfer{logger: log})

log.Info("new terraform", "workingDir", workingDir)

Expand Down Expand Up @@ -664,8 +675,6 @@ func (r *TerraformReconciler) apply(ctx context.Context, terraform infrav1.Terra
return terraform, err
}

tf.SetStdout(os.Stderr)
tf.SetStderr(os.Stderr)
if err := tf.Apply(ctx, tfexec.DirOrPlan(TFPlanName)); err != nil {
err = fmt.Errorf("error running Apply: %s", err)
return infrav1.TerraformNotReady(
Expand All @@ -677,8 +686,6 @@ func (r *TerraformReconciler) apply(ctx context.Context, terraform infrav1.Terra
}

terraform = infrav1.TerraformApplied(terraform, revision, "Terraform Applied Successfully")
tf.SetStdout(nil)
tf.SetStderr(nil)

*outputs, err = tf.Output(ctx)
if err != nil {
Expand Down

0 comments on commit c1387cd

Please sign in to comment.