Compare commits

..

31 commits

Author SHA1 Message Date
7c4cd23e56 [Skip-CI] Fix mastodon add website link 2024-08-06 15:07:51 +02:00
bom
3fd4a72d3d Adjust logic for plan files (version > 1.0.0)
We will no longer try to chdir into files and instead
add them as subcommands.
Includes regression test

Resolves #3 (https://gitlab.com/domaindrivenarchitecture/dda-python-terraform/-/issues/3)
2023-11-24 22:08:38 +01:00
0fb8218dbf [Skip-CI] Add Development and mirrors section 2023-07-28 14:30:52 +02:00
3c92a8b2e6 Change wording 2023-02-15 14:38:56 +01:00
be63bfde3e update doku 2023-01-27 13:20:33 +01:00
a3d97a0d04 fix most pylints 2023-01-27 11:19:03 +01:00
c1c25a016f fix flake8 2023-01-27 10:47:01 +01:00
0abb2370e4 version bump 2023-01-27 10:46:53 +01:00
5af484bcce release 2023-01-27 10:35:48 +01:00
722ba5f716 update the setup.py url to point to the new repository
See merge request domaindrivenarchitecture/dda-python-terraform!3
2023-01-23 16:57:54 +00:00
Marc Seiler
d88670503b update the setup.py url to point to the new repository 2023-01-23 16:57:54 +00:00
bc27522fb5 adjust readme 2022-08-19 15:50:09 +02:00
441bc497d1 version bump 2022-08-19 14:12:20 +02:00
ddb8e4160d release 2022-08-19 14:11:41 +02:00
71c544bad8 Merge branch 'use-semantic-version--string-instead-of-float' into 'master'
[breaking change] use semantic version string

See merge request domaindrivenarchitecture/python-terraform!2
2022-08-19 10:16:40 +00:00
1a7955b738 [breaking change] use semantic version string 2022-08-19 10:16:40 +00:00
9c9d7dc14b add list workspace 2022-08-05 18:09:17 +02:00
f94f3a7c43 adjust gitignore 2022-08-05 18:08:56 +02:00
026e5f260a adjust dev_requirements name 2022-08-05 17:48:19 +02:00
bom
35b52fdbe8 version bump 2022-01-28 09:26:05 +01:00
bom
d44570e9bb release 2022-01-28 09:24:38 +01:00
bom
5e204617d0 fixed releasing doc 2022-01-28 09:23:58 +01:00
bom
7d50eec689 use dda_python_terraform module 2022-01-28 09:17:28 +01:00
bom
b509685c62 rename package 2022-01-27 17:12:33 +01:00
bom
30daf13244 renamed python_terraform to dda_python_terraform 2022-01-27 17:03:30 +01:00
jem
fd431b229d version bump 2022-01-21 13:39:49 +01:00
jem
58e4e9f065 release 2022-01-21 13:37:07 +01:00
jem
124300c271 fix some pylints 2022-01-21 13:36:42 +01:00
jem
382c571d42 release 2022-01-21 13:31:00 +01:00
jem
cb30395d4d release 2022-01-21 13:26:46 +01:00
jem
dcbeb0e934 use protected tags for releasing 2022-01-21 13:23:50 +01:00
11 changed files with 164 additions and 78 deletions

5
.gitignore vendored
View file

@ -12,6 +12,9 @@ dist/
build/
/pytestdebug.log
.pytestdebug.log
/pytest_cache
.lsp
# virtualenv
.virtualenv/
@ -20,6 +23,7 @@ venv/
# Intellij
.idea
.idea/
# VSCode
.vscode/
@ -32,3 +36,4 @@ tmp.txt
/.tox/
env/
Icon
.clj-kondo

View file

@ -4,7 +4,7 @@ before_script:
- python --version
- pip install setuptools wheel twine
- pip install .
- pip install -r dev_requirements.txt
- pip install -r requirements_dev.txt
stages:
- lint
@ -16,21 +16,21 @@ flake8:
stage: lint
allow_failure: true
script:
- flake8 --max-line-length=120 --count --select=E9,F63,F7,F82 --show-source --statistics python_terraform/*.py
- flake8 --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics python_terraform/*.py
- flake8 --max-line-length=120 --count --select=E9,F63,F7,F82 --show-source --statistics dda_python_terraform/*.py
- flake8 --count --exit-zero --max-complexity=13 --max-line-length=127 --statistics --ignore F401 dda_python_terraform/*.py
mypy:
stage: lint
allow_failure: true
script:
- python -m mypy python_terraform/terraform.py
- python -m mypy python_terraform/tfstate.py
- python -m mypy dda_python_terraform/terraform.py
- python -m mypy dda_python_terraform/tfstate.py
pylint:
stage: lint
allow_failure: true
script:
- pylint -d C0301 python_terraform/*.py
- pylint -d C0112,C0115,C0301,R0913,R0903,R0902,R0914,R1705,R1732,W0622 dda_python_terraform/*.py
test-0.13.7:
@ -81,7 +81,7 @@ test-1.1.3:
build:
stage: build
rules:
- if: '$CI_COMMIT_TAG != null'
- if: '$CI_COMMIT_TAG =~ /^release-.*$/'
artifacts:
paths:
- dist/*
@ -91,7 +91,7 @@ build:
pypi:
stage: upload
rules:
- if: '$CI_COMMIT_TAG != null'
- if: '$CI_COMMIT_TAG =~ /^release-.*$/'
script:
- twine upload dist/*
@ -99,7 +99,7 @@ gitlab:
image: registry.gitlab.com/gitlab-org/release-cli:latest
stage: upload
rules:
- if: '$CI_COMMIT_TAG != null'
- if: '$CI_COMMIT_TAG =~ /^release-.*$/'
artifacts:
paths:
- release/*

View file

@ -1,21 +1,21 @@
# dda-python-terraform
[![pipeline status](https://gitlab.com/domaindrivenarchitecture/dda-python-terraform/badges/master/pipeline.svg)](https://gitlab.com/domaindrivenarchitecture/dda-python-terraform/-/commits/main)
[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa.de/images/parts/contact/mastodon36_hue9b2464f10b18e134322af482b9c915e_5501_filter_14705073121015236177.png" width=20 alt="M"> meissa@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@meissa) | [Blog](https://domaindrivenarchitecture.org) | [Website](https://meissa.de)
## Introduction
python-terraform is a python module provide a wrapper of `terraform` command line tool.
dda-python-terraform is a python module provide a wrapper of `terraform` command line tool.
`terraform` is a tool made by Hashicorp, please refer to https://terraform.io/
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
### Status
[![Build Status](https://travis-ci.org/aubustou/python-terraform.svg?branch=develop)](https://travis-ci.org/aubustou/python-terraform)
## Installation
pip install python-terraform
## Usage
#### For any terraform command
from python_terraform import *
from dda_python_terraform import *
t = Terraform()
return_code, stdout, stderr = t.<cmd_name>(*arguments, **options)
@ -23,13 +23,13 @@ python-terraform is a python module provide a wrapper of `terraform` command lin
to be able to call the method, you could call cmd_name by adding `_cmd` after command name, for example,
`import` here could be called by
from python_terraform import *
from dda_python_terraform import *
t = Terraform()
return_code, stdout, stderr = t.import_cmd(*arguments, **options)
or just call cmd method directly
from python_terraform import *
from dda_python_terraform import *
t = Terraform()
return_code, stdout, stderr = t.cmd(<cmd_name>, *arguments, **options)
@ -82,7 +82,7 @@ simply pass the string to arguments of the method, for example,
By default, stdout and stderr are captured and returned. This causes the application to appear to hang. To print terraform output in real time, provide the `capture_output` option with any value other than `None`. This will cause the output of terraform to be printed to the terminal in real time. The value of `stdout` and `stderr` below will be `None`.
from python_terraform import Terraform
from dda_python_terraform import Terraform
t = Terraform()
return_code, stdout, stderr = t.<cmd_name>(capture_output=False)
@ -96,19 +96,19 @@ In shell:
In python-terraform:
from python_terraform import *
from dda_python_terraform import *
tf = Terraform(working_dir='/home/test')
tf.apply(no_color=IsFlagged, refresh=False, var={'a':'b', 'c':'d'})
or
from python_terraform import *
from dda_python_terraform import *
tf = Terraform()
tf.apply('/home/test', no_color=IsFlagged, refresh=False, var={'a':'b', 'c':'d'})
or
from python_terraform import *
from dda_python_terraform import *
tf = Terraform(working_dir='/home/test', variables={'a':'b', 'c':'d'})
tf.apply(no_color=IsFlagged, refresh=False)
@ -120,7 +120,7 @@ In shell:
In python-terraform:
from python_terraform import *
from dda_python_terraform import *
tf = terraform(working_dir='/home/test')
tf.fmt(diff=True)
@ -140,3 +140,12 @@ This make api caller don't have a general rule to follow but to do
a exhaustive method implementation which I don't prefer to.
Therefore I end-up with using `IsFlagged` or `IsNotFlagged` as value of option
like `-no-color` and `True/False` value reserved for option like `refresh=true`
## Development & mirrors
Development happens at: https://repo.prod.meissa.de/meissa/dda-python-terraform
Mirrors are:
* https://gitlab.com/domaindrivenarchitecture/dda-python-terraform (CI issues and PR)
* https://github.com/DomainDrivenArchitecture/dda-python-terraform
For more details about our repository model see: https://repo.prod.meissa.de/meissa/federate-your-repos

View file

@ -1,3 +1,4 @@
"""Module providing wrapper for terraform."""
from .terraform import (
IsFlagged,
IsNotFlagged,

View file

@ -1,3 +1,4 @@
"""Module providing wrapper for terraform."""
import json
import logging
import os
@ -5,8 +6,9 @@ import subprocess
import sys
import tempfile
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
from packaging import version
from python_terraform.tfstate import Tfstate
from dda_python_terraform.tfstate import Tfstate
logger = logging.getLogger(__name__)
@ -29,8 +31,9 @@ CommandOutput = Tuple[Optional[int], Optional[str], Optional[str]]
class TerraformCommandError(subprocess.CalledProcessError):
"""Class representing a terraform error"""
def __init__(self, ret_code: int, cmd: str, out: Optional[str], err: Optional[str]):
super(TerraformCommandError, self).__init__(ret_code, cmd)
super().__init__(ret_code, cmd)
self.out = out
self.err = err
logger.error("Error with command %s. Reason: %s", self.cmd, self.err)
@ -52,7 +55,7 @@ class Terraform:
var_file: Optional[str] = None,
terraform_bin_path: Optional[str] = None,
is_env_vars_included: bool = True,
terraform_version: Optional[float] = 0.13
terraform_semantic_version: Optional[str] = "0.13.0"
):
"""
:param working_dir: the folder of the working folder, if not given,
@ -69,17 +72,18 @@ class Terraform:
:param terraform_bin_path: binary path of terraform
:type is_env_vars_included: bool
:param is_env_vars_included: included env variables when calling terraform cmd
:param terrform_semantic_version encodes major.minor.patch version of terraform. Defaults to 0.13.0
"""
self.is_env_vars_included = is_env_vars_included
self.working_dir = working_dir
self.state = state
self.targets = [] if targets is None else targets
self.variables = dict() if variables is None else variables
self.variables = {} if variables is None else variables
self.parallelism = parallelism
self.terraform_bin_path = (
terraform_bin_path if terraform_bin_path else "terraform"
)
self.terraform_version = terraform_version
self.terraform_semantic_version = terraform_semantic_version
self.var_file = var_file
self.temp_var_files = VariableFiles()
@ -156,7 +160,7 @@ class Terraform:
global_opts = self._generate_default_general_options(dir_or_plan)
default = kwargs.copy()
# force is no longer a flag in version >= 1.0
if self.terraform_version < 1.0:
if version.parse(self.terraform_semantic_version) < version.parse("1.0.0"):
default["force"] = force
default["auto-approve"] = True
options = self._generate_default_options(default)
@ -311,15 +315,15 @@ class Terraform:
if self.is_env_vars_included:
environ_vars = os.environ.copy()
p = subprocess.Popen(
proc = subprocess.Popen(
cmds, stdout=stdout, stderr=stderr, cwd=working_folder, env=environ_vars
)
if not synchronous:
return None, None, None
out, err = p.communicate()
ret_code = p.returncode
out, err = proc.communicate()
ret_code = proc.returncode
logger.info("output: %s", out)
if ret_code == 0:
@ -437,15 +441,43 @@ class Terraform:
global_opts = self._generate_default_general_options(False)
return self.cmd(global_opts, "workspace", "show", **kwargs)
def list_workspace(self) -> List[str]:
"""List of workspaces
:return: workspaces
:example:
>>> tf = Terraform()
>>> tf.list_workspace()
['default', 'test']
"""
global_opts = self._generate_default_general_options(False)
return list(
filter(
lambda workspace: len(workspace) > 0,
map(
lambda workspace: workspace.strip('*').strip(),
(self.cmd(global_opts, "workspace", "list")[1] or '').split()
)
)
)
def _generate_default_args(self, dir_or_plan: Optional[str]) -> Sequence[str]:
if (self.terraform_version < 1.0 and dir_or_plan):
if (version.parse(self.terraform_semantic_version) < version.parse("1.0.0") and dir_or_plan):
return [dir_or_plan]
elif (version.parse(self.terraform_semantic_version) >= version.parse("1.0.0") and dir_or_plan and os.path.isfile(f'{self.working_dir}/{dir_or_plan}')):
plan = dir_or_plan.split('/')[-1]
return [plan]
else:
return []
def _generate_default_general_options(self, dir_or_plan: Optional[str]) -> Dict[str, Any]:
if (self.terraform_version >= 1.0 and dir_or_plan):
return {"chdir": dir_or_plan}
if (version.parse(self.terraform_semantic_version) >= version.parse("1.0.0") and dir_or_plan):
if os.path.isdir(self.working_dir + '/' + dir_or_plan):
return {"chdir": dir_or_plan}
else:
plan_path = dir_or_plan.split('/')
dir_to_plan_path = "/".join(plan_path[:-1])
return {"chdir": dir_to_plan_path}
else:
return {}
@ -464,10 +496,8 @@ class Terraform:
}
def _generate_cmd_options(self, **kwargs) -> List[str]:
"""
"""
result = []
for option, value in kwargs.items():
if "_" in option:
option = option.replace("_", "-")
@ -479,13 +509,12 @@ class Terraform:
if isinstance(value, dict):
if "backend-config" in option:
for bk, bv in value.items():
result += [f"-backend-config={bk}={bv}"]
for backend_key, backend_value in value.items():
result += [f"-backend-config={backend_key}={backend_value}"]
continue
# since map type sent in string won't work, create temp var file for
# variables, and clean it up later
elif option == "var":
if option == "var":
# We do not create empty var-files if there is no var passed.
# An empty var-file would result in an error: An argument or block definition is required here
if value:
@ -507,10 +536,10 @@ class Terraform:
result += [f"-{option}={value}"]
return result
def __exit__(self, exc_type, exc_value, traceback) -> None:
self.temp_var_files.clean_up()
def __getattr__(self, item: str) -> Callable:
def wrapper(*args, **kwargs):
cmd_name = str(item)
@ -522,14 +551,14 @@ class Terraform:
return wrapper
class VariableFiles:
"""Class representing a terraform var files"""
def __init__(self):
self.files = []
def create(self, variables: Dict[str, str]) -> str:
"""create var file in temp"""
with tempfile.NamedTemporaryFile(
"w+t", suffix=".tfvars.json", delete=False
) as temp:
@ -542,7 +571,8 @@ class VariableFiles:
return file_name
def clean_up(self):
for f in self.files:
os.unlink(f.name)
"""cleanup the var file"""
for fle in self.files:
os.unlink(fle.name)
self.files = []

View file

@ -1,3 +1,4 @@
"""Helper Module providing wrapper for terraform state."""
import json
import logging
import os
@ -7,6 +8,7 @@ logger = logging.getLogger(__name__)
class Tfstate:
"""Class representing a terraform state"""
def __init__(self, data: Optional[Dict[str, str]] = None):
self.tfstate_file: Optional[str] = None
self.native_data = data
@ -21,8 +23,8 @@ class Tfstate:
"""
logger.debug("read data from %s", file_path)
if os.path.exists(file_path):
with open(file_path) as f:
json_data = json.load(f)
with open(file_path, encoding="utf-8") as fle:
json_data = json.load(fle)
tf_state = Tfstate(json_data)
tf_state.tfstate_file = file_path

12
doc/releasing.md Normal file
View file

@ -0,0 +1,12 @@
## Release
```
adjust version number in setup.py to release version number.
git commit -am "release"
git tag -am "release" release-[release version no]
git push --follow-tags
increase version no in setup.py
git commit -am "version bump"
git push
pip3 install --upgrade --user dda-python-terraform
```

View file

@ -0,0 +1 @@
packaging

View file

@ -21,14 +21,14 @@ except IOError:
setup(
name=module_name,
version="1.0.2-dev",
url="https://github.com/DomainDrivenArchitecture/python-terraform",
version="2.1.2-dev",
url="https://repo.prod.meissa.de/meissa/dda-python-terraform",
license="MIT",
author="Freddy Tan",
author_email="beelit94@gmail.com",
author="Freddy Tan, meissa team",
author_email="buero@meissa.de",
description=short_description,
long_description=long_description,
packages=["python_terraform"],
packages=["dda_python_terraform"],
package_data={},
platforms="any",
install_requires=dependencies,

View file

@ -6,19 +6,19 @@ import shutil
from contextlib import contextmanager
from io import StringIO
from typing import Callable
from packaging import version
import pytest
from _pytest.logging import LogCaptureFixture, caplog
from python_terraform import IsFlagged, IsNotFlagged, Terraform, TerraformCommandError
from dda_python_terraform import IsFlagged, IsNotFlagged, Terraform, TerraformCommandError
logging.basicConfig(level=logging.DEBUG)
root_logger = logging.getLogger()
current_path = os.path.dirname(os.path.realpath(__file__))
version = 1.0 if (os.environ.get("TFVER") and os.environ.get(
"TFVER").startswith("1")) else 0.13
semantic_version = os.environ.get("TFVER")
FILE_PATH_WITH_SPACE_AND_SPACIAL_CHARS = "test 'test.out!"
STRING_CASES = [
@ -60,7 +60,7 @@ CMD_CASES_0_x = [
var={"test_var": "test"},
raise_on_error=False,
),
# Expected output varies by terraform version
# Expected output varies by terraform semantic_version
"Plan: 0 to add, 0 to change, 0 to destroy.",
0,
False,
@ -131,7 +131,7 @@ CMD_CASES_1_x = [
var={"test_var": "test"},
raise_on_error=False,
),
# Expected output varies by terraform version
# Expected output varies by terraform semantic_version
"Changes to Outputs:",
0,
False,
@ -236,7 +236,7 @@ def workspace_setup_teardown():
@contextmanager
def wrapper(workspace_name, create=True, delete=True, *args, **kwargs):
tf = Terraform(working_dir=current_path, terraform_version=version)
tf = Terraform(working_dir=current_path, terraform_semantic_version=semantic_version)
tf.init()
if create:
tf.create_workspace(workspace_name, *args, **kwargs)
@ -271,14 +271,14 @@ class TestTerraform:
@pytest.mark.parametrize(["method", "expected"], STRING_CASES)
def test_generate_cmd_string(self, method: Callable[..., str], expected: str):
tf = Terraform(working_dir=current_path, terraform_version=version)
tf = Terraform(working_dir=current_path, terraform_semantic_version=semantic_version)
result = method(tf)
strs = expected.split()
for s in strs:
assert s in result
@pytest.mark.parametrize(*(CMD_CASES_1_x if version >= 1.0 else CMD_CASES_0_x))
@pytest.mark.parametrize(*(CMD_CASES_1_x if version.parse(semantic_version) >= version.parse("1.0.0") else CMD_CASES_0_x))
def test_cmd(
self,
method: Callable[..., str],
@ -290,7 +290,7 @@ class TestTerraform:
folder: str,
):
with caplog.at_level(logging.INFO):
tf = Terraform(working_dir=current_path, terraform_version=version)
tf = Terraform(working_dir=current_path, terraform_semantic_version=semantic_version)
tf.init(folder)
try:
ret, out, _ = method(tf)
@ -305,10 +305,10 @@ class TestTerraform:
assert expected_logs in caplog.text
@pytest.mark.parametrize(*(APPLY_CASES_1_x if version >= 1.0 else APPLY_CASES_0_x))
@pytest.mark.parametrize(*(APPLY_CASES_1_x if version.parse(semantic_version) >= version.parse("1.0.0") else APPLY_CASES_0_x))
def test_apply(self, folder, variables, var_files, expected_output, options):
tf = Terraform(
working_dir=current_path, variables=variables, var_file=var_files, terraform_version=version
working_dir=current_path, variables=variables, var_file=var_files, terraform_semantic_version=semantic_version
)
tf.init(folder)
ret, out, err = tf.apply(folder, **options)
@ -316,9 +316,29 @@ class TestTerraform:
assert expected_output in out.replace("\n", "").replace(" ", "")
assert err == ""
def test_apply_plan(self):
# test is only applicable to version > 1.0.0
if version.parse(semantic_version) < version.parse("1.0.0"):
return
tf = Terraform(
working_dir=current_path, terraform_semantic_version=semantic_version
)
out_folder = 'var_to_output'
out_file_name = 'test.out'
out_file_path = f'{out_folder}/{out_file_name}'
tf.init(out_folder)
ret, _, err = tf.plan(out_folder, detailed_exitcode=IsNotFlagged, out=out_file_name)
assert ret == 0
assert err == ""
ret, _, err = tf.apply(out_file_path, skip_plan=True)
assert ret == 0
assert err == ""
def test_apply_with_var_file(self, caplog: LogCaptureFixture):
with caplog.at_level(logging.INFO):
tf = Terraform(working_dir=current_path, terraform_version=version)
tf = Terraform(working_dir=current_path, terraform_semantic_version=semantic_version)
folder = "var_to_output"
tf.init(folder)
tf.apply(
@ -338,7 +358,7 @@ class TestTerraform:
],
)
def test_options(self, cmd, args, options, fmt_test_file):
tf = Terraform(working_dir=current_path, terraform_version=version)
tf = Terraform(working_dir=current_path, terraform_semantic_version=semantic_version)
ret, out, err = getattr(tf, cmd)(*args, **options)
assert ret == 0
assert out == ""
@ -346,26 +366,26 @@ class TestTerraform:
def test_state_data(self):
cwd = os.path.join(current_path, "test_tfstate_file")
tf = Terraform(working_dir=cwd, state="tfstate.test",
terraform_version=version)
terraform_semantic_version=semantic_version)
tf.read_state_file()
assert tf.tfstate.modules[0]["path"] == ["root"]
def test_state_default(self):
cwd = os.path.join(current_path, "test_tfstate_file2")
tf = Terraform(working_dir=cwd, terraform_version=version)
tf = Terraform(working_dir=cwd, terraform_semantic_version=semantic_version)
tf.read_state_file()
assert tf.tfstate.modules[0]["path"] == ["default"]
def test_state_default_backend(self):
cwd = os.path.join(current_path, "test_tfstate_file3")
tf = Terraform(working_dir=cwd, terraform_version=version)
tf = Terraform(working_dir=cwd, terraform_semantic_version=semantic_version)
tf.read_state_file()
assert tf.tfstate.modules[0]["path"] == ["default_backend"]
def test_pre_load_state_data(self):
cwd = os.path.join(current_path, "test_tfstate_file")
tf = Terraform(working_dir=cwd, state="tfstate.test",
terraform_version=version)
terraform_semantic_version=semantic_version)
assert tf.tfstate.modules[0]["path"] == ["root"]
@pytest.mark.parametrize(
@ -373,7 +393,7 @@ class TestTerraform:
)
def test_override_default(self, folder, variables):
tf = Terraform(working_dir=current_path,
variables=variables, terraform_version=version)
variables=variables, terraform_semantic_version=semantic_version)
tf.init(folder)
ret, out, err = tf.apply(
folder, var={"test_var": "test2"}, no_color=IsNotFlagged,
@ -389,7 +409,7 @@ class TestTerraform:
required_output = "test_output"
with caplog.at_level(logging.INFO):
tf = Terraform(
working_dir=current_path, variables={"test_var": expected_value}, terraform_version=version
working_dir=current_path, variables={"test_var": expected_value}, terraform_semantic_version=semantic_version
)
tf.init("var_to_output")
tf.apply("var_to_output")
@ -403,7 +423,7 @@ class TestTerraform:
def test_destroy(self):
tf = Terraform(working_dir=current_path, variables={
"test_var": "test"}, terraform_version=version)
"test_var": "test"}, terraform_semantic_version=semantic_version)
tf.init("var_to_output")
ret, out, err = tf.destroy("var_to_output")
assert ret == 0
@ -414,7 +434,7 @@ class TestTerraform:
)
def test_plan(self, plan, variables, expected_ret):
tf = Terraform(working_dir=current_path,
variables=variables, terraform_version=version)
variables=variables, terraform_semantic_version=semantic_version)
tf.init(plan)
with pytest.raises(TerraformCommandError) as e:
tf.plan(plan)
@ -424,7 +444,7 @@ class TestTerraform:
def test_fmt(self, fmt_test_file):
tf = Terraform(working_dir=current_path, variables={
"test_var": "test"}, terraform_version=version)
"test_var": "test"}, terraform_semantic_version=semantic_version)
ret, out, err = tf.fmt(diff=True)
assert ret == 0
@ -529,3 +549,9 @@ class TestTerraform:
in caplog.messages
)
"""
def test_list_workspace(self):
tf = Terraform(working_dir=current_path)
workspaces = tf.list_workspace()
assert len(workspaces) > 0
assert 'default' in workspaces