Skip to content

Commit

Permalink
Add support for command line specified variables (string or read file)
Browse files Browse the repository at this point in the history
Also bumps version to 0.0.5.
  • Loading branch information
KARBOWSKI Piotr committed Jun 9, 2020
1 parent b5ee257 commit defbbf9
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
35 changes: 31 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,32 @@ The template and variable file(s) can be either local, or remote s3, if prefixed

::

usage: j2rt [-h] -t TEMPLATE_FROM -v VARIABLES_FROM [VARIABLES_FROM ...] [-o OUTPUT]
usage: j2rt [-h] -t TEMPLATE_FROM
[-v VARIABLES_FROM [VARIABLES_FROM ...]]
[-V VARIABLE [VARIABLE ...]] [-o OUTPUT] [--version]

optional arguments:
-h, --help show this help message and exit
-t TEMPLATE_FROM, --template-from TEMPLATE_FROM
Path to template file to use
-v VARIABLES_FROM [VARIABLES_FROM ...], --variables-from VARIABLES_FROM [VARIABLES_FROM ...]
The path(s) for JSON files from which variables will be taken
from, if variable in file is already defined, it will be
The path(s) for JSON files from which
variables will be taken from, if variable in
file is already defined, it will be
overwritten.
-V VARIABLE [VARIABLE ...], --variable VARIABLE [VARIABLE ...]
Set variable from command line, in the format
name=value, prefix value with @ to read file
into variable, one can escape @ by writting it
as @@foo for @foo value. Variables specified
at command line have highest priority and will
overrride the same variable set in any of
--variables-from.
-o OUTPUT, --output OUTPUT
Output file, if not set, result is printed to stdout.
Output file, if not set, result is printed to
stdout.
--version Show version and exit


Examples
--------
Expand Down Expand Up @@ -77,3 +91,16 @@ Generate .env with production configuration and secrets, taking secrets from (en
-t .env.j2 \
-v .env.base.json .env.prod.json s3://somebucket/.env.prod.secrets.json \
-o .env

Generate OpenVPN client config file, taking CA.crt from S3 bucket, while client certificate and other keys taken from local file system::

j2rt \
--template-from /etc/openvpn/client.ovpn.j2 \
--variables-from /etc/openvpn/base_configuration_subnets_routing_tables_etc.json \
--variable \
server_name=TEST_SERVER \
CA_CRT=@s3://somebucket/ca.crt \
client_crt=@/path/to/pki/certs/client1.crt \
client_key=@/path/to/pki/keys/client1.key \
ta_key=@/etc/openvpn/ta.key \
-o /root/client1.ovpn
45 changes: 40 additions & 5 deletions src/j2rt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ def process_args():
)

parser.add_argument(
'-v', '--variables-from', action='append', nargs='+', required=True,
'-v', '--variables-from', action='append', nargs='+',
help="The path(s) for JSON files from which variables will be taken from, if variable in file is already defined, it will be overwritten."
)

parser.add_argument(
'-V', '--variable', action='append', nargs='+',
help="Set variable from command line, in the format name=value, prefix value with @ to read file into variable, one can escape @ by writting it as @@foo for @foo value. Variables specified at command line have highest priority and will overrride the same variable set in any of --variables-from."
)

parser.add_argument(
'-o', '--output', action='store', required=False,
help="Output file, if not set, result is printed to stdout."
Expand All @@ -41,6 +46,9 @@ def process_args():
parser.print_help(sys.stderr)
sys.exit(1)

if not (args.variables_from or args.variable):
parser.error('At least one of --variables-from or --variable is required')

return args, extra_args


Expand All @@ -55,11 +63,15 @@ def read_file(path, providers):
return Path(path).read_text()


def collect_input(template_from, variables_from):
def collect_input(template_from, variables_from, single_variables):
variables = {}

providers = {}
if template_from.startswith('s3://') or any(item.startswith('s3://') for item in variables_from):
if (
template_from.startswith('s3://') or
any(item.startswith('s3://') for item in variables_from) or
any('=@s3://' in item for item in single_variables)
):
# Late initialize boto3's s3 client, only if s3 is in use
# to make sure script works without boto3 if no s3 is required.
import boto3
Expand All @@ -74,15 +86,38 @@ def collect_input(template_from, variables_from):
)
)

for variable in single_variables:
if '=' not in variable:
raise ValueError("Wrong format '{}'".format(variable))

name, value = variable.split("=", 1)

if value[:1] == '@':
if value[1:2] == '@':
variables.update({name: value[1:]})
else:
variables.update({name: read_file(value[1:], providers)})
else:
variables.update({name: value})

return template, variables


def render(args):
# Python before 3.8 did not had action='extend' in argsparse, so to make it just work
# we will flatten the list of lists from action='append'.
variables_from = [item for sublist in args.variables_from for item in sublist]

template, variables = collect_input(args.template_from, variables_from)
if args.variables_from:
variables_from = [item for sublist in args.variables_from for item in sublist]
else:
variables_from = []

if args.variable:
single_variables = [item for sublist in args.variable for item in sublist]
else:
single_variables = []

template, variables = collect_input(args.template_from, variables_from, single_variables)

env = jinja2.Environment(
loader=jinja2.BaseLoader(),
Expand Down
2 changes: 1 addition & 1 deletion src/j2rt/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = "0.0.4"
version = "0.0.5"

0 comments on commit defbbf9

Please sign in to comment.