Skip to content

Commit 0aaed9b

Browse files
First version
1 parent d7b2211 commit 0aaed9b

File tree

8 files changed

+164
-1
lines changed

8 files changed

+164
-1
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.pyc
2+
build/
3+
dist/
4+
terrafile.egg-info/

Makefile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
$(eval NAME := $(shell python setup.py --name))
2+
$(eval PY_NAME := $(shell python setup.py --name | sed 's/-/_/g'))
3+
$(eval VERSION := $(shell python setup.py --version))
4+
5+
SDIST := dist/$(NAME)-$(VERSION).tar.gz
6+
WHEEL := dist/$(PY_NAME)-$(VERSION)-py2.py3-none-any.whl
7+
8+
.PHONY: all
9+
all: build
10+
11+
$(SDIST):
12+
python setup.py sdist
13+
14+
$(WHEEL):
15+
python setup.py bdist_wheel
16+
17+
.PHONY: build
18+
build: $(SDIST) $(WHEEL)
19+
20+
.PHONY: install
21+
install: $(WHEEL)
22+
pip install --user $(WHEEL)
23+
24+
.PHONY: uninstall
25+
uninstall:
26+
pip uninstall $(NAME)
27+
28+
.PHONY: upload
29+
upload: $(SDIST) $(WHEEL)
30+
twine upload $(SDIST) $(WHEEL)
31+
32+
.PHONY: clean
33+
clean:
34+
rm -rf build dist *.egg-info

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,19 @@
11
# python-terrafile
2-
Manages external Terraform modules
2+
3+
Manages external Terraform modules, controlled by a `Terrafile`.
4+
5+
This is basically a Python version of the tool described at [http://bensnape.com/2016/01/14/terraform-design-patterns-the-terrafile/](http://bensnape.com/2016/01/14/terraform-design-patterns-the-terrafile/)
6+
7+
## Installation
8+
9+
```shell
10+
pip install terrafile
11+
```
12+
13+
## Usage
14+
15+
```shell
16+
terrafile [path]
17+
```
18+
19+
If `path` is provided, it must be the path to a `Terrafile` file, or a directory containing one. If not provided, it looks for the file in the current working directory.

bin/terrafile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
python -m terrafile "$@"

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[wheel]
2+
universal = 1

setup.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python
2+
3+
from setuptools import setup
4+
5+
setup(
6+
name='terrafile',
7+
version='0.1',
8+
description='Manages external Terraform modules.',
9+
author='Raymond Butcher',
10+
author_email='[email protected]',
11+
url='https://github.com/claranet/python-terrafile',
12+
license='MIT License',
13+
packages=(
14+
'terrafile',
15+
),
16+
scripts=(
17+
'bin/terrafile',
18+
),
19+
install_requires=(
20+
'pyyaml',
21+
),
22+
)

terrafile/__init__.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import errno
2+
import os
3+
import shutil
4+
import subprocess
5+
import sys
6+
import yaml
7+
8+
9+
def run(*args, **kwargs):
10+
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
11+
stdout, stderr = proc.communicate()
12+
return (stdout, proc.returncode)
13+
14+
15+
def get_terrafile_path(path):
16+
if os.path.isdir(path):
17+
return os.path.join(path, 'Terrafile')
18+
else:
19+
return path
20+
21+
22+
def read_terrafile(path):
23+
try:
24+
with open(path) as open_file:
25+
terrafile = yaml.load(open_file)
26+
if not terrafile:
27+
raise ValueError('{} is empty'.format(path))
28+
except IOError as error:
29+
sys.stderr.write('Error loading Terrafile: {}\n'.format(error.strerror))
30+
sys.exit(1)
31+
except ValueError as error:
32+
sys.stderr.write('Error loading Terrafile: {}\n'.format(error))
33+
sys.exit(1)
34+
else:
35+
return terrafile
36+
37+
38+
def has_git_tag(path, tag):
39+
tags = set()
40+
if os.path.isdir(path):
41+
output, returncode = run('git', 'tag', '--points-at=HEAD', cwd=path)
42+
if returncode == 0:
43+
tags.update(output.split())
44+
return tag in tags
45+
46+
47+
def update_modules(path):
48+
terrafile_path = get_terrafile_path(path)
49+
module_path = os.path.dirname(terrafile_path)
50+
module_path_name = os.path.basename(os.path.abspath(module_path))
51+
52+
terrafile = read_terrafile(terrafile_path)
53+
54+
for name, repository_details in sorted(terrafile.items()):
55+
source = repository_details['source']
56+
version = repository_details['version']
57+
target = os.path.join(module_path, name)
58+
59+
# Skip this module if it has already been checked out.
60+
if has_git_tag(path=target, tag=version):
61+
print('Fetched {}/{}'.format(module_path_name, name))
62+
continue
63+
64+
print('Fetching {}/{}'.format(module_path_name, name))
65+
66+
# Delete the old directory and clone it from scratch.
67+
shutil.rmtree(target, ignore_errors=True)
68+
output, returncode = run('git', 'clone', '--branch={}'.format(version), source, target)
69+
if returncode != 0:
70+
sys.stderr.write(output)
71+
sys.exit(returncode)

terrafile/__main__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import os
2+
import sys
3+
4+
from terrafile import update_modules
5+
6+
if len(sys.argv) > 1:
7+
path = sys.argv[1]
8+
else:
9+
path = os.getcwd()
10+
11+
update_modules(path)

0 commit comments

Comments
 (0)