Skip to content
This repository has been archived by the owner on Sep 13, 2023. It is now read-only.

Commit

Permalink
backend: drop dvc-specific working-dir behavior (#17)
Browse files Browse the repository at this point in the history
* backend: get rid of dvc-specific make_tf behavior

- drop make_tf contextmanager
- use single working_dir per TerraformBackend instance (instead of
  nesting by resource name)

* update tests

* make default_resource public
  • Loading branch information
pmrowla authored Oct 8, 2021
1 parent 4188d71 commit fc779c4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 38 deletions.
13 changes: 3 additions & 10 deletions tests/test_terraform.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import os

import pytest
from mock import ANY, MagicMock
Expand Down Expand Up @@ -66,7 +65,7 @@ def terraform(tmp_path, mocker):
@pytest.fixture
def resource(tmp_path):
name = "test-resource"
path = tmp_path / name / "terraform.tfstate"
path = tmp_path / "terraform.tfstate"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(TEST_RESOURCE_STATE, encoding="utf-8")
yield name
Expand All @@ -92,21 +91,15 @@ def test_make_pemfile():
assert fobj.read() == content


def test_make_tf(terraform):
name = "foo"
with terraform.make_tf(name) as tf:
assert tf.working_dir == os.path.join(terraform.tmp_dir, name)


def test_create(tmp_path, terraform):
name = "foo"
terraform.create(name=name, cloud="aws")
terraform.cmd_mock.assert_any_call("init", capture_output=False)
terraform.cmd_mock.assert_any_call(
"apply", capture_output=False, auto_approve=IsFlagged
)
assert (tmp_path / name / "main.tf.json").exists()
with open(tmp_path / name / "main.tf.json") as fobj:
assert (tmp_path / "main.tf.json").exists()
with open(tmp_path / "main.tf.json") as fobj:
data = json.load(fobj)
assert data["resource"]["iterative_machine"] == {
name: {"name": name, "cloud": "aws"},
Expand Down
44 changes: 16 additions & 28 deletions tpi/terraform.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import asyncio
import os
import sys
from contextlib import contextmanager
from itertools import repeat
from typing import TYPE_CHECKING, Iterator, Optional, Union

Expand All @@ -18,22 +17,14 @@ class TPIException(Exception):


class TerraformBackend:
def __init__(self, tmp_dir: StrPath, **kwargs):
self.tmp_dir = tmp_dir
os.makedirs(self.tmp_dir, exist_ok=True)
"""Class for managing a named TPI iterative-machine resource."""

@contextmanager
def make_tf(self, name: str):
from tpi import TerraformProviderIterative, TPIError
def __init__(self, working_dir: StrPath, **kwargs):
from tpi import TerraformProviderIterative

try:
working_dir = os.path.join(self.tmp_dir, name)
os.makedirs(working_dir, exist_ok=True)
yield TerraformProviderIterative(working_dir=working_dir)
except TPIError:
raise
except Exception as exc:
raise TPIError("terraform failed") from exc
self.working_dir = working_dir
os.makedirs(self.working_dir, exist_ok=True)
self.tf = TerraformProviderIterative(working_dir=self.working_dir)

def create(self, name: Optional[str] = None, **config):
"""Create and start an instance of the specified machine."""
Expand All @@ -42,29 +33,26 @@ def create(self, name: Optional[str] = None, **config):
from tpi import render_json

assert name and "cloud" in config
with self.make_tf(name) as tf:
tf_file = os.path.join(tf.working_dir, "main.tf.json")
with open(tf_file, "w", encoding="utf-8") as fobj:
fobj.write(render_json(name=name, **config, indent=2))
tf.cmd("init")
tf.cmd("apply", auto_approve=IsFlagged)
tf_file = os.path.join(self.working_dir, "main.tf.json")
with open(tf_file, "w", encoding="utf-8") as fobj:
fobj.write(render_json(name=name, **config, indent=2))
self.tf.cmd("init")
self.tf.cmd("apply", auto_approve=IsFlagged)

def destroy(self, name: Optional[str] = None, **config):
"""Stop and destroy all instances of the specified machine."""
from python_terraform import IsFlagged

assert name

with self.make_tf(name) as tf:
if first(tf.iter_instances(name)):
tf.cmd("destroy", auto_approve=IsFlagged)
if first(self.tf.iter_instances(name)):
self.tf.cmd("destroy", auto_approve=IsFlagged)

def instances(self, name: Optional[str] = None, **config) -> Iterator[dict]:
"""Iterate over status of all instances of the specified machine."""
assert name

with self.make_tf(name) as tf:
yield from tf.iter_instances(name)
yield from self.tf.iter_instances(name)

def close(self):
pass
Expand All @@ -73,7 +61,7 @@ def run_shell(self, name: Optional[str] = None, **config):
"""Spawn an interactive SSH shell for the specified machine."""
from tpi import TerraformProviderIterative

resource = self._default_resource(name)
resource = self.default_resource(name)
with TerraformProviderIterative.pemfile(resource) as pem:
self._shell(
host=resource["instance_ip"],
Expand All @@ -82,7 +70,7 @@ def run_shell(self, name: Optional[str] = None, **config):
known_hosts=None,
)

def _default_resource(self, name):
def default_resource(self, name):
from tpi import TPIError

resource = first(self.instances(name))
Expand Down

0 comments on commit fc779c4

Please sign in to comment.