Skip to content

Commit c0f9feb

Browse files
author
Patrick McCarthy
committed
Added in dynamic version support
1 parent b64fd5d commit c0f9feb

File tree

3 files changed

+66
-4
lines changed

3 files changed

+66
-4
lines changed

Diff for: README.md

+13
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ example:
9595
source: "https://github.com/joeblogs/example.git"
9696
version: "master"
9797
```
98+
99+
## Dynamic Version support
100+
Once you modularize your terraform modules and begin versioning them. The consuming terrafile repo, see environments example above often requires separate PR against it just to uptake the latest version. In non prod environments you might want to bypass this by utilizing dynamic versioning.
101+
You can use dynamic versioning to allow auto update, so instead of just having master as the version, you can provide tf1.+, or tf1.3.+ etc... to provide more flexibility.
102+
When might you require more flexibility:
103+
Often terraform is kept in a subfolder alondside the service source code, but it will be released on a different cadence, so it should have its own independent versioning. For example you may be using semantic versioning for your service code, v1.0,0, but you want to distinguish terraform changes using a different prefix, for example tf1.0.0 In this way you can release terraform changes separately to service code changes. If you have pure terraform modules you can then use same prefix tfx.x.x
104+
Terraform versioning isn't quite the same as semantic versioning for application code.
105+
First digit indicates manual changes that need to be applied,
106+
Second digit indicates a change that could be automatically applied(you may not have automatic system yet, but still use this critieria until you do)
107+
Third digit is for hotpatch fixes. You have something in production but you cannot rollback, or apply all the changes in your module since, so you branch at production version and release a patch version.
108+
109+
110+
98111

99112
## Local installation, useful for Testing (python 3)
100113
```shell

Diff for: terrafile/__init__.py

+49-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,53 @@ def add_github_token(github_download_url,token):
4141
return url
4242

4343

44+
def prevent_injection(input_variable):
45+
if ';' in format(input_variable):
46+
print("No semi colons allowed !!! input variable = {}".format(input_variables))
47+
sys.exit(1)
48+
49+
50+
def retrieve_tag_refs(l_refs, grep_version):
51+
prevent_injection(grep_version)
52+
remote_refs = {}
53+
refs = set()
54+
refs = ([t.decode('utf-8') for t in l_refs.split()])
55+
grep_version = grep_version.replace('+','\d*')
56+
grep_version = grep_version.replace('.','\.')
57+
for ref in refs:
58+
if ref is '':
59+
break
60+
hash_ref_list = ref.split('\t')
61+
versionre = re.compile('refs/tags/({}.*$)'.format(grep_version))
62+
m = versionre.match(hash_ref_list[0])
63+
if m:
64+
remote_refs[m.group(1)] = "found"
65+
return m.group(1)
66+
67+
logger.info("Version {} doesn't exist in repo ".format(grep_version))
68+
sys.exit(1)
69+
70+
71+
def conform_to_version_format(version, source, grep_version):
72+
special_git_versions = ['master',' MASTER', 'HEAD', 'head']
73+
version_prefix = "^[{}]+[\d.|\+]+[\+|-]*[\w]*$".format(grep_version)
74+
if version not in special_git_versions and '+' in version:
75+
pattern = re.compile("{}".format(version_prefix))
76+
validVersionFormat = pattern.match(version)
77+
if not validVersionFormat:
78+
sys.stderr.write('version {} format isnt valid {}\n'.format(version,version_prefix))
79+
sys.exit(1)
80+
git_output ,returncode = run("/usr/bin/git", "ls-remote","--tags", "--sort=-v:refname", "--exit-code", "--refs", "{}".format(source))
81+
if returncode != 0:
82+
sys.stderr.write('problem with git ls-remote {}\n'.format(git_output))
83+
sys.exit(1)
84+
output = retrieve_tag_refs(git_output, version)
85+
return output
86+
return version
87+
88+
4489
def run(*args, **kwargs):
90+
prevent_injection(args)
4591
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
4692
stdout, stderr = proc.communicate()
4793
return (stdout, proc.returncode)
@@ -149,7 +195,7 @@ def clone_remote_git( source, target, module_path, name, version):
149195
if 'GITHUB_TOKEN' in os.environ:
150196
source = self._add_github_token(source, os.getenv('GITHUB_TOKEN'))
151197
# Delete the old directory and clone it from scratch.
152-
print('Fetching {}/{}'.format(os.path.basename(os.path.abspath(module_path)), name))
198+
print('Fetching {}/{} at version {}'.format(os.path.basename(os.path.abspath(module_path)), name, version))
153199
shutil.rmtree(target, ignore_errors=True)
154200
output, returncode = run('git', 'clone', '--branch={}'.format(version), source, target)
155201
if returncode != 0:
@@ -176,7 +222,7 @@ def filter_modules(terrafile,found_modules):
176222
return remove_dups(terrafile)
177223

178224

179-
def update_modules(path, optimize_downloads):
225+
def update_modules(path, optimize_downloads, grep_version):
180226
terrafile_path = get_terrafile_path(path)
181227
module_path = os.path.dirname(terrafile_path)
182228
module_path_name = os.path.basename(os.path.abspath(module_path))
@@ -204,7 +250,7 @@ def update_modules(path, optimize_downloads):
204250
continue
205251

206252
version = repository_details['version']
207-
253+
version = conform_to_version_format(version, source, grep_version)
208254
# Support Terraform Registry sources.
209255
if is_valid_registry_source(source):
210256
print('Checking {}/{}'.format(module_path_name, name))

Diff for: terrafile/__main__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from terrafile import update_modules
66

77
optimizedownloads = False
8+
versionprefix = "tf"
89
if len(sys.argv) < 3:
910
if len(sys.argv) < 2:
1011
path = os.getcwd()
@@ -14,9 +15,11 @@
1415
parser = argparse.ArgumentParser()
1516
parser.add_argument('--terrafile', required=False, default=os.getcwd(), dest='path', help='location of Terrafile')
1617
parser.add_argument('--optimizedownloads', required=False, default=False, dest='optimizedownloads', help='Switch on opinionated distinct module downloads')
18+
parser.add_argument('--versionprefix', required=False, default="tf", dest='versionprefix', help='terraform module version prefix tf or v as in tf1.0.0 or v1.0.0')
19+
1720
args = parser.parse_args()
1821
path = args.path
1922
optimizedownloads = args.optimizedownloads
2023

2124

22-
update_modules(path, optimizedownloads)
25+
update_modules(path, optimizedownloads, versionprefix)

0 commit comments

Comments
 (0)