Skip to content

Commit

Permalink
feat(RHTAPREL-392): add jinja2 and templating to the image
Browse files Browse the repository at this point in the history
As part of RHTAPREL-392, we need to create advisories. The easiest way
to do this is from a template using jinja2, so this commit adds jinja2
and a template to the repo. Some ansible filters are not present in
vanilla jinja2, so a module providing those is added too.

Signed-off-by: Johnny Bieren <[email protected]>
  • Loading branch information
johnbieren committed Oct 10, 2023
1 parent ecbbfc8 commit 922ba2e
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@ RUN dnf -y --setopt=tsflags=nodocs install \
jq \
python39-devel \
diffutils \
python39-pip \
python39-requests \
skopeo \
krb5-workstation \
&& dnf clean all

RUN pip3 install jinja2 \
jinja2-ansible-filters

ADD data/certs/2015-IT-Root-CA.pem data/certs/2022-IT-Root-CA.pem /etc/pki/ca-trust/source/anchors/
RUN update-ca-trust

COPY pyxis /home/pyxis
COPY utils /home/utils
COPY templates /home/templates

# Set HOME variable to something else than `/` to avoid 'permission denied' problems when writing files.
ENV HOME=/tekton/home
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pytest
requests
jinja2
jinja2-ansible-filters
23 changes: 23 additions & 0 deletions templates/advisory.yaml.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: rhtap.redhat.com/v1alpha1
kind: Advisory
metadata:
name: {{ advisory_name }}
spec:
product_id: {{ advisory.spec.product_id }}
cpe: {{ advisory.spec.cpe }}
type: {{ advisory.spec.type }}
{%- if 'issues' in advisory.spec %}
issues:
{{ advisory.spec.issues | to_nice_yaml(indent=2) | indent(4) | trim }}
{%- endif %}
content:
{{ advisory.spec.content | to_nice_yaml(indent=2) | indent(4) | trim }}
synopsis: {{ advisory.spec.synopsis }}
topic: >-
{{ advisory.spec.topic | wordwrap(76) | indent(4) }}
description: >-
{{ advisory.spec.description | wordwrap(76) | indent(4) }}
solution: >-
{{ advisory.spec.solution | wordwrap(76) | indent(4) }}
references:
{{ advisory.spec.references | to_nice_yaml | indent(4) }}
51 changes: 51 additions & 0 deletions utils/apply_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
from jinja2 import Template
from jinja2_ansible_filters import AnsibleCoreFiltersExtension
import argparse
import json


def setup_argparser() -> argparse.Namespace: # pragma: no cover
"""Setup argument parser
:return: Initialized argument parser
"""

parser = argparse.ArgumentParser(description="Applies a template.")

parser.add_argument(
"--data",
help="JSON string containing data to use in the template.",
required=True,
)
parser.add_argument(
"--template",
help="Path to the template file to use.",
required=True,
)
parser.add_argument(
"-o",
"--output",
help="The desired filename of the result.",
required=True,
)
return parser.parse_args()


def main(): # pragma: no cover
"""Main func"""

args = setup_argparser()

with open(args.template) as t:
template = Template(t.read(), extensions=[AnsibleCoreFiltersExtension])
content = template.render(json.loads(args.data))

filename = args.output
with open(filename, mode="w", encoding="utf-8") as advisory:
advisory.write(content)
print(f"Wrote {filename}")


if __name__ == "__main__": # pragma: no cover
main()
44 changes: 44 additions & 0 deletions utils/test_apply_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest
from unittest.mock import patch, MagicMock
from apply_template import setup_argparser, main


@patch(
"argparse._sys.argv",
["apply_template", "--data", "{}", "--template", "somefile", "-o", "newfile"],
)
def test_setup_argparser_proper_args():
args_out = setup_argparser()
assert args_out.data == "{}"
assert args_out.template == "somefile"
assert args_out.output == "newfile"


def test_setup_argparser_improper_args():
with pytest.raises(SystemExit) as e:
setup_argparser()
assert e.value.code == 2


@patch("builtins.open")
@patch("apply_template.Template.render")
@patch("apply_template.setup_argparser")
def test_apply_template_advisory_template(
mock_argparser: MagicMock, mock_render: MagicMock, mock_open: MagicMock
):
args = MagicMock()
args.template = "templates/advisory.yaml.jinja"
args.data = "{}"
args.output = "somefile"
mock_argparser.return_value = args
mock_render.return_value = "applied template file"
mock_open1 = MagicMock()
mock_open2 = MagicMock()
mock_open.side_effect = [mock_open1, mock_open2]
mock_open1.__enter__.return_value.read.side_effect = "foo: bar"
file = mock_open2.__enter__.return_value

# Act
main()

file.write.assert_called_once_with("applied template file")

0 comments on commit 922ba2e

Please sign in to comment.