1
0
mirror of https://github.com/oskar456/dzonegit.git synced 2024-05-11 05:55:41 +00:00

Add config template generator

This commit is contained in:
Ondřej Caletka
2018-07-16 15:31:55 +02:00
parent e3abe11448
commit dfae21f1ff
2 changed files with 82 additions and 15 deletions

View File

@ -6,9 +6,11 @@ import subprocess
import re import re
import time import time
import datetime import datetime
import json
from collections import namedtuple from collections import namedtuple
from hashlib import sha256 from hashlib import sha256
from pathlib import Path from pathlib import Path
from string import Template
class HookException(ValueError): class HookException(ValueError):
@ -265,6 +267,51 @@ def replace_serial(path, oldserial, newserial):
path.write_text(updated) path.write_text(updated)
def template_config(checkoutpath, template):
""" Recursively find all *.zone files and template config file using
a simple JSON based template like this:
{
"header": "# Managed by dzonegit, do not edit.\n",
"footer": "",
"item": " - zone: \"$zonename\"\n file: \"$zonefile\"\n $zonevar\n",
"defaultvar": "template: default",
"zonevars": {
"example.com": "template: signed"
}
}
Available placeholders are:
- $datetime - timestamp of file creation
- $zonename - zone name, without trailing dot
- $zonefile - full path to zone file
- $zonevar - per-zone specific variables, content of `defaultvar` if
not defined for current zone
"""
tpl = json.loads(template)
headertpl = Template(tpl.get("header", ""))
footertpl = Template(tpl.get("footer", ""))
itemtpl = Template(tpl.get("item", ""))
defaultvar = tpl.get("defaultvar", "")
zonevars = tpl.get("zonevars", dict())
out = list()
zones = set()
mapping = {"datetime": datetime.datetime.now().strftime("%c")}
out.append(headertpl.substitute(mapping))
for f in Path(checkoutpath).glob("**/*.zone"):
zonename = get_zone_name(f, f.read_bytes())
if zonename in zones:
continue # Safety net in case duplicate zone file is found
zones.add(zonename)
zonevar = zonevars[zonename] if zonename in zonevars else defaultvar
out.append(itemtpl.substitute(
mapping, zonename=zonename,
zonefile=str(f), zonevar=zonevar,
))
out.append(footertpl.substitute(mapping))
return "\n".join(out)
def do_commit_checks(against, revision=None, autoupdate_serial=False): def do_commit_checks(against, revision=None, autoupdate_serial=False):
try: try:
if not get_config("dzonegit.ignorewhitespaceerrors", bool): if not get_config("dzonegit.ignorewhitespaceerrors", bool):
@ -323,16 +370,23 @@ def post_receive(stdin=sys.stdin):
added or delefed. added or delefed.
""" """
suffixes = list(str(n) if n else "" for n in range(10)) suffixes = list(str(n) if n else "" for n in range(10))
for s in suffixes: checkoutpath = get_config("dzonegit.checkoutpath")
d = get_config("dzonegit.checkoutpath{}".format(s)) if checkoutpath:
if d: print("Checking out repository into {}".format(checkoutpath))
print("Checking out repository into {}".format(d)) subprocess.run(
subprocess.run( ["git", "checkout", "-f", "master"],
["git", "checkout", "-f", "master"], check=True,
check=True, env=dict(os.environ, GIT_WORK_TREE=checkoutpath),
env=dict(os.environ, GIT_WORK_TREE=d), )
for s in suffixes:
cfpath = get_config("dzonegit.conffilepath{}".format(s))
tplpath = get_config("dzonegit.conffiletemplate{}".format(s))
if cfpath is None or tplpath is None:
continue
print("Templating config file {}".format(cfpath))
Path(cfpath).write_text(
template_config(checkoutpath, Path(tplpath).read_text()),
) )
# TODO config
if stdin.isatty(): if stdin.isatty():
raise SystemExit( raise SystemExit(

View File

@ -273,10 +273,23 @@ def test_post_receive(git_dir):
git_dir.chdir() git_dir.chdir()
revisions = "{} {} ".format("0"*40, dzonegit.get_head()) revisions = "{} {} ".format("0"*40, dzonegit.get_head())
stdin = StringIO(revisions + "refs/heads/master\n") stdin = StringIO(revisions + "refs/heads/master\n")
codir1 = git_dir.mkdir("co1") codir = git_dir.mkdir("co")
codir2 = git_dir.mkdir("co2") subprocess.call(["git", "config", "dzonegit.checkoutpath", str(codir)])
subprocess.call(["git", "config", "dzonegit.checkoutpath", str(codir1)])
subprocess.call(["git", "config", "dzonegit.checkoutpath9", str(codir2)])
dzonegit.post_receive(stdin) dzonegit.post_receive(stdin)
assert codir1.join("dummy.zone").check() assert codir.join("dummy.zone").check()
assert codir2.join("dummy.zone").check()
def test_template_config(git_dir):
template = r"""{
"header": "# Managed by dzonegit on $datetime, do not edit.\n",
"footer": "# This is the end",
"item": " - zone: \"$zonename\"\n file: \"$zonefile\"\n $zonevar\n",
"defaultvar": "template: default",
"zonevars": {
"example.com": "template: signed"
}
}"""
output = dzonegit.template_config(str(git_dir), template)
assert output.startswith("# Managed by dzonegit")
assert " - zone: \"dummy\"\n file: \"" in output
assert output.endswith("# This is the end")