Skip to content

Commit

Permalink
Merge pull request #91 from TomasTomecek/better-vars-expansion
Browse files Browse the repository at this point in the history
Fix variable expansion: referencing local vars within vars
  • Loading branch information
TomasTomecek authored Mar 16, 2019
2 parents b286e73 + 6fe9588 commit 2bd49cd
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 27 deletions.
1 change: 1 addition & 0 deletions ansible_bender/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
OUT_LOGGER = "ab-out"
OUT_LOGGER_FORMAT = "%(message)s"
TIMESTAMP_FORMAT = "%Y%m%d-%H%M%S%f"
TIMESTAMP_FORMAT_TOGETHER = "%Y%m%d%H%M%S%f"
NO_CACHE_TAG = "no-cache"

# configuration related constants
Expand Down
47 changes: 28 additions & 19 deletions ansible_bender/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
...
"""
import copy
import datetime
import json
import logging
Expand All @@ -43,7 +44,7 @@
import ansible_bender
from ansible_bender import callback_plugins
from ansible_bender.conf import ImageMetadata, Build
from ansible_bender.constants import TIMESTAMP_FORMAT
from ansible_bender.constants import TIMESTAMP_FORMAT, TIMESTAMP_FORMAT_TOGETHER
from ansible_bender.exceptions import AbBuildUnsuccesful
from ansible_bender.utils import run_cmd, ap_command_exists, random_str, graceful_get, \
is_ansibles_python_2
Expand Down Expand Up @@ -241,7 +242,7 @@ def expand_pb_vars(self):
"""
populate vars from a playbook, defined in vars section
:return: dict
:return: dict with the content of ansible_bender var
"""
with open(self.playbook_path) as fd:
plays = yaml.safe_load(fd)
Expand All @@ -259,38 +260,49 @@ def expand_pb_vars(self):

bender_vars = graceful_get(d, "vars", "ansible_bender")
if not bender_vars:
logger.info("no bender data found in the playbook")
return {}

tmp = tempfile.mkdtemp(prefix="ab")
json_data_path = os.path.join(tmp, "j.json")

# we cannot use "vars" variable because the variables are not expanded in there
pb_vars = copy.deepcopy(d["vars"])
while True:
# just in case the variable is already defined
timestamp = datetime.datetime.now().strftime(TIMESTAMP_FORMAT_TOGETHER)
ab_vars_key = f"ab_vars_{timestamp}"
if ab_vars_key not in pb_vars:
logger.debug("ab vars key = %s", ab_vars_key)
pb_vars[ab_vars_key] = d["vars"]
break
jinja_pb_vars_key = '{{ %s }}' % ab_vars_key
pb = {
"name": "Let Ansible expand variables",
"hosts": "localhost",
"vars": {
"ab_vars": d["vars"],
},
"vars": pb_vars,
"vars_files": d.get("vars_files", []),
"gather_facts": False,
"tasks": [
{"debug": {"msg": "{{ ab_vars }}"}},
{"debug": {"msg": jinja_pb_vars_key}},
{
"copy": {
"dest": json_data_path,
"content": '{{ ab_vars }}'
"content": jinja_pb_vars_key
}
}
]
}

i_path = os.path.join(tmp, "i")
with open(i_path, "w") as fd:
fd.write("localhost ansible_connection=local")

tmp_pb_path = os.path.join(tmp, "p.yaml")
tmp_pb_path = os.path.join(tmp, "p.json")
with open(tmp_pb_path, "w") as fd:
yaml.safe_dump([pb], fd)
json.dump([pb], fd)

playbook_base = os.path.basename(self.playbook_path).split(".", 1)[0]
timestamp = datetime.datetime.now().strftime(TIMESTAMP_FORMAT)
symlink_name = f".{playbook_base}-{timestamp}-{random_str()}.yaml"
playbook_dir = os.path.dirname(self.playbook_path)
symlink_path = os.path.join(playbook_dir, symlink_name)
Expand All @@ -304,22 +316,19 @@ def expand_pb_vars(self):
provide_output=False, log_stderr=True, ansible_args=args)

with open(json_data_path) as fd:
return json.load(fd)
return json.load(fd)["ansible_bender"]
finally:
os.unlink(symlink_path)
shutil.rmtree(tmp)

def process_pb_vars(self, playbook_vars):
def process_pb_vars(self, bender_data):
"""
accept variables from the playbook and update the Build and ImageMetadata objects with them
:param playbook_vars: dict with all the playbook variables
:param bender_data: dict with the content of ansible_bender vars
:return:
"""
try:
bender_data = playbook_vars["ansible_bender"]
except KeyError:
logger.info("no bender data found in the playbook")
if not bender_data:
return
self.metadata.update_from_configuration(bender_data.get("target_image", {}))
self.build.update_from_configuration(bender_data)
Expand All @@ -330,8 +339,8 @@ def get_build_and_metadata(self):
:return: Build(), ImageMetadata()
"""
data = self.expand_pb_vars()
bender_data = self.expand_pb_vars()

self.process_pb_vars(data)
self.process_pb_vars(bender_data)

return self.build, self.metadata
2 changes: 1 addition & 1 deletion tests/data/full_conf_pb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
annotations:
bohemian: rhapsody
environment:
z: x
z: '{{ key }}'
cmd: command -x -y z
user: leonardo

Expand Down
14 changes: 7 additions & 7 deletions tests/integration/test_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
def test_expand_pb_vars():
p = PbVarsParser(b_p_w_vars_path)
data = p.expand_pb_vars()
assert data["ansible_bender"]["base_image"] == "docker.io/library/python:3-alpine"
assert data["ansible_bender"]["ansible_extra_args"] == "-vvv"
assert data["base_image"] == "docker.io/library/python:3-alpine"
assert data["ansible_extra_args"] == "-vvv"
playbook_dir = os.path.dirname(b_p_w_vars_path)
assert data["ansible_bender"]["working_container"]["volumes"] == [f"{playbook_dir}:/src"]
assert data["ansible_bender"]["target_image"]["name"] == "challet"
assert data["ansible_bender"]["target_image"]["labels"] == {"x": "y"}
assert data["ansible_bender"]["target_image"]["environment"] == {"asd": playbook_dir}
assert data["working_container"]["volumes"] == [f"{playbook_dir}:/src"]
assert data["target_image"]["name"] == "challet"
assert data["target_image"]["labels"] == {"x": "y"}
assert data["target_image"]["environment"] == {"asd": playbook_dir}


def test_b_m_empty():
Expand Down Expand Up @@ -59,7 +59,7 @@ def test_set_all_params():
assert b.build_volumes == ["/c:/d"]
assert b.target_image == "funky-mona-lisa"

assert m.env_vars == {"z": "x"}
assert m.env_vars == {"z": "value"}
assert m.volumes == ["/a"]
assert m.working_dir == "/workshop"
assert m.labels == {"x": "y"}
Expand Down

0 comments on commit 2bd49cd

Please sign in to comment.