Skip to content

Instantly share code, notes, and snippets.

@zanglang
Created January 17, 2017 07:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zanglang/ddfd7decc1331dcbcc59a2c0cb0d4ce2 to your computer and use it in GitHub Desktop.
Save zanglang/ddfd7decc1331dcbcc59a2c0cb0d4ce2 to your computer and use it in GitHub Desktop.
Ansible module that takes in a target Java .properties file, and patches in any arbitrary key-value properties specified in a JSON hash format
#!/usr/local/python/bin/python
"""
Ansible module that takes in a target Java .properties file, and patches in any
arbitrary key-value properties specified in a JSON hash format. This module is
expected to be used alongside the `properties` Ansible action module.
Examples:
- properties:
dest: ~/dists/cluster/ix/ZookeeperIndexMerger.properties
props:
helloStr: Hello world!
@author: Jerry Chong <jchong@netbase.com>
@tags: WANT_JSON
"""
from __future__ import print_function
import json
import os
import re
import sys
from six import StringIO
def decode(path):
"""Load a JSON file from the given path"""
jsonfile = open(path)
return json.load(jsonfile)
def process(target, properties):
"""
Performs simple string replacements to generate a new .properties file at
the `target` path, using the `properties` key-value mapping
"""
# shallow copy since we will need to modify this dict later
src_dict = properties.copy()
buffer = StringIO()
keys = src_dict.keys()
prop_re = re.compile(r"^(?P<comment>#*\s*)(?P<key>[\w.]+)\s*=\s*(?P<val>.*?)?;?\s*$")
with open(target, "r+") as propfile:
for line in propfile.readlines():
line = line.strip()
match = prop_re.match(line)
# if line does have key=value pattern, otherwise simply write it
if match:
commented, key, val = match.groups(default='')
# replace in target INI file if replacement value is defined
if key in keys:
line = "{}{}={}".format(commented, key, str(src_dict[key]))
src_dict.pop(key)
buffer.write(line + "\n")
# append any unreplaced key/values in as extra lines
for key in sorted(src_dict.keys()):
buffer.write(key + "=" + str(src_dict[key]) + "\n")
# write to disk
propfile.seek(0)
propfile.write(buffer.getvalue())
def main():
"""Main function"""
data = decode(sys.argv[1])
result = {"msg": "OK"}
# basic checking
try:
if not data:
raise Exception("JSON data not loaded!")
target = data.get("target") or data.get("dest")
props = data.get("props")
if target is None or props is None:
raise Exception("JSON data is missing 'target' or 'props' attributes!")
elif not isinstance(props, dict):
raise Exception("'props' is not a dict!")
elif not os.path.exists(target):
raise Exception("Target %s does not exist!" % target)
process(target, props)
result["msg"] = "Finished replacing " + target
except Exception as e:
result['failed'] = True
result['msg'] = str(e)
print(json.dumps(result))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment