From a401f9bb0936d7936dd34ad34adf700f4ad741a7 Mon Sep 17 00:00:00 2001 From: Nils Balkow-Tychsen Date: Tue, 6 Aug 2024 12:47:26 +0200 Subject: [PATCH] add opentofu --- .github/workflows/ci.yml | 3 ++ TerraformLibrary/terraformlibrary.py | 18 ++++++--- atest/atest-opentofu.robot | 39 ++++++++++++++++++++ atest/{atest.robot => atest-terraform.robot} | 2 +- docs/terraformlibrary.html | 2 +- utest/test_terraformlibrary.py | 6 +++ 6 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 atest/atest-opentofu.robot rename atest/{atest.robot => atest-terraform.robot} (95%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1961cf4..7e69781 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,9 @@ jobs: uses: hashicorp/setup-terraform@v3 with: terraform_version: "1.5.7" + + - name: Install OpenTofu + uses: opentofu/setup-opentofu@v1 - name: Run tests run: | diff --git a/TerraformLibrary/terraformlibrary.py b/TerraformLibrary/terraformlibrary.py index abf717c..5df85fd 100644 --- a/TerraformLibrary/terraformlibrary.py +++ b/TerraformLibrary/terraformlibrary.py @@ -69,6 +69,14 @@ class TerraformLibrary: with any terraform script. """ + def __init__(self, executable="terraform"): + """ + The TerraformLibrary can either use the terraform executable (default) or can be configured + to run OpenTofu instead by setting the executable to `tofu`. + | ***** Settings ***** + | Library TerraformLibrary executable=tofu + """ + self.exec = executable def _run_command(self, command: str, include_stderr: bool = False): process = subprocess.run( @@ -92,7 +100,7 @@ def terraform_init(self, script_path: str): Returns the return code and the output of the terraform command. """ - command = f"terraform -chdir={script_path} init -no-color" + command = f"{self.exec} -chdir={script_path} init -no-color" rc, output = self._run_command(command, include_stderr=True) return rc, output @@ -108,7 +116,7 @@ def terraform_plan(self, script_path: str): Returns the return code and the output of the terraform command. """ - command = f"terraform -chdir={script_path} plan -no-color -input=false" + command = f"{self.exec} -chdir={script_path} plan -no-color -input=false" rc, output = self._run_command(command, include_stderr=True) return rc, output @@ -124,7 +132,7 @@ def terraform_apply(self, script_path: str): Returns the return code and the output of the terraform command. """ - command = f"terraform -chdir={script_path} apply -auto-approve -no-color -input=false" + command = f"{self.exec} -chdir={script_path} apply -auto-approve -no-color -input=false" rc, output = self._run_command(command, include_stderr=True) return rc, output @@ -140,7 +148,7 @@ def terraform_destroy(self, script_path: str): Returns the return code and the output of the terraform command. """ - command = f"terraform -chdir={script_path} destroy -auto-approve -no-color -input=false" + command = f"{self.exec} -chdir={script_path} destroy -auto-approve -no-color -input=false" rc, output = self._run_command(command, include_stderr=True) return rc, output @@ -172,7 +180,7 @@ def get_terraform_state(self, script_path: str): | Should Be Equal As Strings | ${output["values"]["root_module"]["resources"][0]["name"]} | name of the first resource | """ - command = f"terraform -chdir={script_path} show --json" + command = f"{self.exec} -chdir={script_path} show --json" rc, output = self._run_command(command) output_json = json.loads(output) return output_json diff --git a/atest/atest-opentofu.robot b/atest/atest-opentofu.robot new file mode 100644 index 0000000..c4d4e29 --- /dev/null +++ b/atest/atest-opentofu.robot @@ -0,0 +1,39 @@ +*** Settings *** +Library TerraformLibrary executable=tofu + +*** Variables *** +${TESTDATA} ${CURDIR}/testdata + +*** Test Cases *** +Run Terraform Init + ${rc} ${output} Terraform Init ${TESTDATA}/simple + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} has been successfully initialized! + +Run Terraform Plan + Set TF Var my_var test_value + ${rc} ${output} Terraform Plan ${TESTDATA}/simple + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} Plan: 1 to add, 0 to change, 0 to destroy. + Should Contain ${output} + my_output = "test_value" + +Run Terraform Apply + ${rc} ${output} Terraform Apply ${TESTDATA}/simple + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} Apply complete! Resources: 1 added, 0 changed, 0 destroyed. + Should Contain ${output} my_output = "test_value" + +Inspect Terraform State + ${output} Get Terraform State ${TESTDATA}/simple + Should Be Equal As Strings ${output["values"]["root_module"]["resources"][0]["name"]} foo + +Run Terraform Destroy + ${rc} ${output} Terraform Destroy ${TESTDATA}/simple + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} Destroy complete! Resources: 1 destroyed. + Should Contain ${output} - my_output = "test_value" -> null + +Terraform Error Is Raised + ${rc} ${output} Terraform Plan ${TESTDATA}/tf-error + Should Be Equal As Integers ${rc} 1 + Should Contain ${output} Error: Reference to undeclared input variable \ No newline at end of file diff --git a/atest/atest.robot b/atest/atest-terraform.robot similarity index 95% rename from atest/atest.robot rename to atest/atest-terraform.robot index 04197fd..d369373 100644 --- a/atest/atest.robot +++ b/atest/atest-terraform.robot @@ -8,7 +8,7 @@ ${TESTDATA} ${CURDIR}/testdata Run Terraform Init ${rc} ${output} Terraform Init ${TESTDATA}/simple Should Be Equal As Integers ${rc} 0 - Should Contain ${output} Terraform has been successfully initialized! + Should Contain ${output} has been successfully initialized! Run Terraform Plan Set TF Var my_var test_value diff --git a/docs/terraformlibrary.html b/docs/terraformlibrary.html index 7a0376e..50e7145 100644 --- a/docs/terraformlibrary.html +++ b/docs/terraformlibrary.html @@ -1191,7 +1191,7 @@ jQuery.extend({highlight:function(e,t,n,r){if(e.nodeType===3){var i=e.data.match(t);if(i){var s=document.createElement(n||"span");s.className=r||"highlight";var o=e.splitText(i.index);o.splitText(i[0].length);var u=o.cloneNode(true);s.appendChild(u);o.parentNode.replaceChild(s,o);return 1}}else if(e.nodeType===1&&e.childNodes&&!/(script|style)/i.test(e.tagName)&&!(e.tagName===n.toUpperCase()&&e.className===r)){for(var a=0;a diff --git a/utest/test_terraformlibrary.py b/utest/test_terraformlibrary.py index 79a8fa9..766d401 100644 --- a/utest/test_terraformlibrary.py +++ b/utest/test_terraformlibrary.py @@ -44,3 +44,9 @@ def test_terraform_error(): rc, output = terraform.terraform_plan(f"{testdata_directory}/tf-error") assert rc == 1 assert "Error: Reference to undeclared input variable" in output + +def test_lib_init_opentofu(): + terraform.__init__(executable="tofu") + rc, output = terraform.terraform_init(f"{testdata_directory}/simple") + assert rc == 0 + assert "OpenTofu has been successfully initialized!" in output \ No newline at end of file