Example #1
0
def test_nested_lists_with_value_file(tmp_path):
    p = tmp_path / "test.yaml"
    p.write_text(yaml.dump({"a": ["b", "c"]}))
    # We replace
    resolved = resolve(["a.0=new"], [str(p)])
    assert resolved == {"a": ["new", "c"]}

    # We append
    resolved = resolve(["a.2=d"], [str(p)])
    assert resolved == {"a": ["b", "c", "d"]}

    # The index '3' is out of bound (neither a replacement nor an append)
    with pytest.raises(ValueError):
        resolve(["a.3=new"], [str(p)])
Example #2
0
def test_cli_values_value_files():
    values = resolve([], [VALUES_STAGING_FILE])
    with open(VALUES_STAGING_FILE) as fd:
        assert values == yaml.load(fd)

    # putting the same file twice should not change the resulting values
    assert resolve([], [VALUES_STAGING_FILE, VALUES_STAGING_FILE]) == values

    # cli values override values from files
    assert resolve(["env=production"],
                   [VALUES_STAGING_FILE])["env"] == "production"

    # multiple values override (last wins)
    assert resolve(["env=1", "env=2"], [VALUES_STAGING_FILE])["env"] == "2"

    # nested override
    assert (resolve(
        ["nodeSelector.node-label=pool-2"],
        [VALUES_STAGING_FILE])["nodeSelector"]["node-label"] == "pool-2")
Example #3
0
def test_resolve_invalid_values(values):
    with pytest.raises(ValueError):
        resolve(values, [])
Example #4
0
def test_nested_lists(values, expected):
    assert resolve(values, []) == Context(*expected)
Example #5
0
def test_valid_values(values, expected):
    assert resolve(values, []) == Context(*expected)
Example #6
0
def test_value_files_override():
    values = resolve([], [VALUES_STAGING_FILE])
    assert values["nodeSelector"]["node-label"] == "pool-1"

    values = resolve([], [VALUES_STAGING_FILE, VALUES_PRODUCTION_FILE])
    assert values["nodeSelector"]["node-label"] == "pool-2"
Example #7
0
def test_nested_lists_invalid_index():
    with pytest.raises(ValueError, match=".* list 'a' has not been given a value."):
        resolve(["a.1=v1"], [])
Example #8
0
def test_nested_dicts(values, expected):
    assert resolve(values, []) == expected
Example #9
0
def test_valid_values(values, expected):
    assert resolve(values, []) == expected
Example #10
0
def cli():
    """kuku: Kubernetes templating tool.

    Usage:
      kuku apply [-v] [-f <FILE>]... [-s <key=value>]... <TEMPLATES_DIR>
      kuku delete [-v] [-f <FILE>]... [-s <key=value>]... <TEMPLATES_DIR>
      kuku render [-v] [-f <FILE>]... [-s <key=value>]... <TEMPLATES_DIR>
      kuku (-h | --help)
      kuku --version

    Options:
      -h --help                     Show this screen.
      -v --verbose                  Dump debug info to stderr.
      --version                     Show version.
      -s KEY=VALUE --set KEY=VALUE  Set values on the command line (accepts multiple options or separate values with commas: Ex: -s key1=val1,key2=val2).
      -f FILE --file FILE           Specify values in a YAML file (accepts multiple options).

    Notes:
      Resolution of values: --set overrides values in --file by merging. The last value wins.
    """

    # Parse cli arguments from docstring
    arguments = docopt(str(cli.__doc__), version=__version__)

    # Load k8s config -- needed to the correct API versions of k8s
    config.load_kube_config()

    # Find all templates
    try:
        templates = find(arguments["<TEMPLATES_DIR>"])
    except ValueError as e:
        print(e)
        exit(1)
        raise

    try:
        # Resolve values
        context = resolve(arguments["--set"], arguments["--file"])
    except ValueError as e:
        print(e)
        exit(1)
        raise

    # Render templates with resolved context
    rendering = render(context, templates)

    if not context.is_complete:
        print(f"Missing values: {context.missing_keys}")
        exit(1)

    output = dump(rendering)
    if arguments["render"]:
        # print yaml
        print(output)

    if arguments["apply"]:
        print("Not implemented yet. Use kuku render ... | kubectl apply -f-")
        exit(1)

    if arguments["delete"]:
        print("Not implemented yet. Use kuku render ... | kubectl delete -f-")
        exit(1)

    if arguments["--verbose"]:
        print(output, file=sys.stderr)