Skip to content

Commit

Permalink
Merge pull request #26 from ClarkSource/#23
Browse files Browse the repository at this point in the history
[#23] fail properly for undefined values instead of templating empty string
  • Loading branch information
AFriemann authored Feb 6, 2020
2 parents 1065785 + 3d0656a commit d16afa2
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 98 deletions.
13 changes: 9 additions & 4 deletions k8t/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import click
import coloredlogs
from jinja2.exceptions import UndefinedError
from termcolor import colored

import k8t
Expand Down Expand Up @@ -130,10 +131,14 @@ def cli_gen(method, value_files, cli_values, cname, ename, directory): # pylint
if not validated:
sys.exit(1)

for template_path in templates:
print("---")
print("# Source: {}".format(template_path))
print(eng.get_template(template_path).render(vals))
try:
for template_path in templates:
print("---")
print("# Source: {}".format(template_path))
print(eng.get_template(template_path).render(vals))
except UndefinedError as err:
print(colored("✗ -> {}".format(err), "red"))
sys.exit(1)


@root.group(help="Code scaffolding commands.")
Expand Down
6 changes: 3 additions & 3 deletions k8t/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

import logging

from jinja2 import Environment, FileSystemLoader
from jinja2 import Environment, FileSystemLoader, StrictUndefined

from k8t.filters import b64decode, b64encode, envvar, hashf, random_password
from k8t.project import find_files
from k8t.secrets import get_secret
from k8t.util import b64decode, b64encode, envvar, hashf, random_password

LOGGER = logging.getLogger(__name__)

Expand All @@ -24,7 +24,7 @@ def build(path: str, cluster: str, environment: str):
LOGGER.debug(
"building template environment")

env = Environment(loader=FileSystemLoader(template_paths))
env = Environment(undefined=StrictUndefined, loader=FileSystemLoader(template_paths))

env.filters["b64decode"] = b64decode
env.filters["b64encode"] = b64encode
Expand Down
82 changes: 82 additions & 0 deletions k8t/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
# ISC License
#
# Copyright 2019 FL Fintech E GmbH
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#
# Copyright © 2020 Clark Germany GmbH
# Author: Aljosha Friemann <[email protected]>

import base64
import hashlib
import os
import string
from typing import Any

try:
from secrets import choice
except ImportError:
from random import SystemRandom

choice = SystemRandom().choice


def random_password(length: int) -> str:
return "".join(
choice(string.ascii_lowercase + string.digits) for _ in range(length)
)


def envvar(key: str, default=None) -> str:
return os.environ.get(key, default)


def b64encode(value: Any) -> str:
result = None

if isinstance(value, str):
result = base64.b64encode(value.encode()).decode()
elif isinstance(value, int):
result = base64.b64encode(str(value).encode()).decode()
elif isinstance(value, bytes):
result = base64.b64encode(value).decode()
else:
raise TypeError("invalid input: {}".format(value))

return result


def b64decode(value: Any) -> str:
result = None

if isinstance(value, str):
result = base64.b64decode(value.encode()).decode()
elif isinstance(value, bytes):
result = base64.b64decode(value).decode()
else:
raise TypeError("invalid input: {}".format(value))

return result

def hashf(value, method="sha256"):
try:
hash_method = getattr(hashlib, method)()
except AttributeError:
raise RuntimeError("No such hash method: {}".format(method))

if isinstance(value, str):
hash_method.update(value.encode())
elif isinstance(value, bytes):
hash_method.update(value)
else:
raise TypeError("invalid input: {}".format(value))

return hash_method.hexdigest()



# vim: fenc=utf-8:ts=4:sw=4:expandtab
69 changes: 4 additions & 65 deletions k8t/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,17 @@
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import base64
import copy
import hashlib
import logging
import os
import string
from functools import reduce
from typing import Any, Dict, List
from typing import Dict, List

import yaml
from simple_tools.interaction import confirm

LOGGER = logging.getLogger(__name__)

try:
from secrets import choice
except ImportError:
from random import SystemRandom

choice = SystemRandom().choice


def random_password(length: int) -> str:
return "".join(
choice(string.ascii_lowercase + string.digits) for _ in range(length)
)


# def include_file(name: str):
# fpath = find_file(name, path, cluster, environment)
Expand All @@ -42,48 +26,6 @@ def random_password(length: int) -> str:
# return s.read()


def b64encode(value: Any) -> str:
result = None

if isinstance(value, str):
result = base64.b64encode(value.encode()).decode()
elif isinstance(value, int):
result = base64.b64encode(str(value).encode()).decode()
elif isinstance(value, bytes):
result = base64.b64encode(value).decode()
else:
raise TypeError("invalid input: {}".format(value))

return result


def b64decode(value: Any) -> str:
result = None

if isinstance(value, str):
result = base64.b64decode(value.encode()).decode()
elif isinstance(value, bytes):
result = base64.b64decode(value).decode()
else:
raise TypeError("invalid input: {}".format(value))

return result


def hashf(value, method="sha256"):
try:
hash_method = getattr(hashlib, method)()
except AttributeError:
raise RuntimeError("No such hash method: {}".format(method))

if isinstance(value, str):
hash_method.update(value.encode())
elif isinstance(value, bytes):
hash_method.update(value)
else:
raise TypeError("invalid input: {}".format(value))

return hash_method.hexdigest()


def touch(fname: str, mode=0o666, dir_fd=None, **kwargs) -> None:
Expand Down Expand Up @@ -159,9 +101,6 @@ def load_yaml(path: str) -> dict:
return yaml.safe_load(stream) or dict()


def envvar(key: str, default=None) -> str:
return os.environ.get(key, default)


def envvalues() -> Dict:
prefix: str = 'K8T_VALUE_'
Expand All @@ -174,14 +113,14 @@ def envvalues() -> Dict:
return values


def list_files(directory: str, files=False, directories=False) -> List[str]:
def list_files(directory: str, include_files=False, include_directories=False) -> List[str]:
result = []

for _, dirs, files in os.walk(directory):
if files:
if include_files:
result.extend(files)

if directories:
if include_directories:
result.extend(dirs)

break
Expand Down
16 changes: 16 additions & 0 deletions tests/engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# ISC License
#
# Copyright 2019 FL Fintech E GmbH
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#
# Copyright © 2020 Clark Germany GmbH
# Author: Aljosha Friemann <[email protected]>

from k8t.engine import build

# vim: fenc=utf-8:ts=4:sw=4:expandtab
42 changes: 42 additions & 0 deletions tests/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# ISC License
#
# Copyright 2019 FL Fintech E GmbH
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#
# Copyright © 2020 Clark Germany GmbH
# Author: Aljosha Friemann <[email protected]>

import random

from k8t.filters import b64decode, b64encode, hashf, random_password


def test_b64encode():
string = "foobar"

encoded = b64encode(string)

assert encoded != string
assert b64decode(encoded) == string


def test_random_password():
length = int(random.uniform(1, 200))

assert len(random_password(length)) == length
assert random_password(length) != random_password(length)


def test_hashf():
string = "foobar"

assert hashf(string) != string
assert hashf(string) == hashf(string)
assert hashf(string) != hashf("foobaz")

# vim: fenc=utf-8:ts=4:sw=4:expandtab
16 changes: 16 additions & 0 deletions tests/templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# ISC License
#
# Copyright 2019 FL Fintech E GmbH
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#
# Copyright © 2020 Clark Germany GmbH
# Author: Aljosha Friemann <[email protected]>

from k8t.templates import analyze

# vim: fenc=utf-8:ts=4:sw=4:expandtab
27 changes: 1 addition & 26 deletions tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

import random

from k8t.util import (b64decode, b64encode, deep_merge, hashf, merge,
random_password)
from k8t.util import deep_merge, merge


def test_merge_memory_safety():
Expand Down Expand Up @@ -48,27 +47,3 @@ def test_deep_merge():

assert (
deep_merge(dict_c, dict_b, dict_a) == dict(foo=dict(a=1, b=2), baz=4, bar=dict(a=3, c=9)))


def test_b64encode():
string = "foobar"

encoded = b64encode(string)

assert encoded != string
assert b64decode(encoded) == string


def test_random_password():
length = int(random.uniform(1, 200))

assert len(random_password(length)) == length
assert random_password(length) != random_password(length)


def test_hashf():
string = "foobar"

assert hashf(string) != string
assert hashf(string) == hashf(string)
assert hashf(string) != hashf("foobaz")

0 comments on commit d16afa2

Please sign in to comment.