Skip to content

Commit 6c79130

Browse files
authored
Add support to scaffold execution environment sample file (#340)
* Add support to scaffold execution environment sample file * Changes to arg parser and constants
1 parent 68679f8 commit 6c79130

File tree

8 files changed

+177
-1
lines changed

8 files changed

+177
-1
lines changed

.config/dictionary.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ myuser
2727
netcommon
2828
nilashish
2929
notesdir
30+
PYCMD
3031
pydoclint
3132
rulebook
3233
rulebooks
34+
sshpass
3335
sysargs
3436
templated
3537
templating

src/ansible_creator/arg_parser.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ def _add_resource(self, subparser: SubParser[ArgumentParser]) -> None:
233233
self._add_resource_devcontainer(subparser=subparser)
234234
self._add_resource_devfile(subparser=subparser)
235235
self._add_resource_role(subparser=subparser)
236+
self._add_resource_execution_env(subparser=subparser)
236237

237238
def _add_resource_devcontainer(self, subparser: SubParser[ArgumentParser]) -> None:
238239
"""Add devcontainer files to an existing Ansible project.
@@ -312,6 +313,29 @@ def _add_resource_role(self, subparser: SubParser[ArgumentParser]) -> None:
312313
)
313314
self._add_args_common(parser)
314315

316+
def _add_resource_execution_env(self, subparser: SubParser[ArgumentParser]) -> None:
317+
"""Add execution environment sample file to an existing path.
318+
319+
Args:
320+
subparser: The subparser to add execution environment file to
321+
"""
322+
parser = subparser.add_parser(
323+
"execution-environment",
324+
help="Add a sample execution-environment.yml file to an existing path.",
325+
formatter_class=CustomHelpFormatter,
326+
)
327+
328+
parser.add_argument(
329+
"path",
330+
default="./",
331+
metavar="path",
332+
help="The destination directory for the execution environment file. "
333+
"The default is the current working directory.",
334+
)
335+
336+
self._add_overwrite(parser)
337+
self._add_args_common(parser)
338+
315339
def _add_plugin(self, subparser: SubParser[ArgumentParser]) -> None:
316340
"""Add a plugin to an Ansible project.
317341

src/ansible_creator/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
),
1515
"DEV_FILE_IMAGE": "ghcr.io/ansible/ansible-workspace-env-reference:latest",
1616
"RECOMMENDED_EXTENSIONS": ["redhat.ansible", "redhat.vscode-redhat-account"],
17+
"EXECUTION_ENVIRONMENT_DEFAULT_IMAGE": "quay.io/fedora/fedora:41",
1718
}
1819

1920
MIN_COLLECTION_NAME_LEN = 2
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
version: 3
3+
4+
images:
5+
base_image:
6+
name: {{ execution_environment_image }}
7+
8+
dependencies:
9+
ansible_core:
10+
package_pip: ansible-core
11+
12+
ansible_runner:
13+
package_pip: ansible-runner
14+
15+
system:
16+
- openssh-clients
17+
- sshpass
18+
19+
python:
20+
- requests
21+
- boto3
22+
23+
galaxy:
24+
collections:
25+
- name: ansible.posix
26+
- name: ansible.utils
27+
28+
additional_build_steps:
29+
append_base:
30+
- RUN $PYCMD -m pip install -U pip
31+
32+
options:
33+
tags:
34+
- ansible_sample_ee

src/ansible_creator/subcommands/add.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ def _resource_scaffold(self) -> None:
105105
template_data = self._get_devfile_template_data()
106106
elif self._resource_type == "devcontainer":
107107
template_data = self._get_devcontainer_template_data()
108-
108+
elif self._resource_type == "execution-environment":
109+
template_data = self._get_ee_template_data()
109110
else:
110111
msg = f"Unsupported resource type: {self._resource_type}"
111112
raise CreatorError(msg)
@@ -281,3 +282,14 @@ def _get_plugin_template_data(self) -> TemplateData:
281282
plugin_name=self._plugin_name,
282283
creator_version=self._creator_version,
283284
)
285+
286+
def _get_ee_template_data(self) -> TemplateData:
287+
"""Get the template data for lookup plugin.
288+
289+
Returns:
290+
TemplateData: Data required for templating the lookup plugin.
291+
"""
292+
return TemplateData(
293+
resource_type=self._resource_type,
294+
creator_version=self._creator_version,
295+
)

src/ansible_creator/types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class TemplateData:
2727
dev_file_image: The devfile image.
2828
dev_file_name: The unique name entry in devfile.
2929
namespace: The namespace of the collection.
30+
execution_environment_image: The execution environment image.
3031
recommended_extensions: A list of recommended VsCode extensions.
3132
"""
3233

@@ -40,6 +41,9 @@ class TemplateData:
4041
dev_file_image: Sequence[str] = GLOBAL_TEMPLATE_VARS["DEV_FILE_IMAGE"]
4142
dev_file_name: str = ""
4243
namespace: str = ""
44+
execution_environment_image: Sequence[str] = GLOBAL_TEMPLATE_VARS[
45+
"EXECUTION_ENVIRONMENT_DEFAULT_IMAGE"
46+
]
4347
recommended_extensions: Sequence[str] = field(
4448
default_factory=lambda: GLOBAL_TEMPLATE_VARS["RECOMMENDED_EXTENSIONS"],
4549
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
version: 3
3+
4+
images:
5+
base_image:
6+
name: quay.io/fedora/fedora:41
7+
8+
dependencies:
9+
ansible_core:
10+
package_pip: ansible-core
11+
12+
ansible_runner:
13+
package_pip: ansible-runner
14+
15+
system:
16+
- openssh-clients
17+
- sshpass
18+
19+
python:
20+
- requests
21+
- boto3
22+
23+
galaxy:
24+
collections:
25+
- name: ansible.posix
26+
- name: ansible.utils
27+
28+
additional_build_steps:
29+
append_base:
30+
- RUN $PYCMD -m pip install -U pip
31+
32+
options:
33+
tags:
34+
- ansible_sample_ee

tests/units/test_add.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,3 +696,68 @@ def mock_check_collection_path() -> None:
696696
with pytest.raises(CreatorError) as exc_info:
697697
add.run()
698698
assert "Unsupported plugin type: unsupported_type" in str(exc_info.value)
699+
700+
701+
def test_run_success_add_execution_env(
702+
capsys: pytest.CaptureFixture[str],
703+
tmp_path: Path,
704+
cli_args: ConfigDict,
705+
monkeypatch: pytest.MonkeyPatch,
706+
) -> None:
707+
"""Test Add.run() for adding a execution-environment sample file.
708+
709+
Successfully adds execution-environment.yml sample file to path.
710+
711+
Args:
712+
capsys: Pytest fixture to capture stdout and stderr.
713+
tmp_path: Temporary directory path.
714+
cli_args: Dictionary, partial Add class object.
715+
monkeypatch: Pytest monkeypatch fixture.
716+
"""
717+
# Set the resource_type to execution-environment
718+
cli_args["resource_type"] = "execution-environment"
719+
add = Add(
720+
Config(**cli_args),
721+
)
722+
add.run()
723+
result = capsys.readouterr().out
724+
assert re.search("Note: Resource added to", result) is not None
725+
726+
# Verify the generated execution-environment file match the expected structure
727+
expected_ee_file = tmp_path / "execution-environment.yml"
728+
effective_ee_file = (
729+
FIXTURES_DIR / "common" / "execution-environment" / "execution-environment.yml"
730+
)
731+
732+
cmp_result = cmp(expected_ee_file, effective_ee_file, shallow=False)
733+
assert cmp_result
734+
735+
# Test for overwrite prompt and failure with no overwrite option
736+
conflict_file = tmp_path / "execution-environment.yml"
737+
conflict_file.write_text('{ "version": "1" }')
738+
739+
# expect a CreatorError when the response to overwrite is no.
740+
monkeypatch.setattr("builtins.input", lambda _: "n")
741+
fail_msg = (
742+
"The destination directory contains files that will be overwritten."
743+
" Please re-run ansible-creator with --overwrite to continue."
744+
)
745+
with pytest.raises(
746+
CreatorError,
747+
match=fail_msg,
748+
):
749+
add.run()
750+
751+
# expect a warning followed by execution-environment resource creation msg
752+
# when response to overwrite is yes.
753+
monkeypatch.setattr("builtins.input", lambda _: "y")
754+
add.run()
755+
result = capsys.readouterr().out
756+
assert (
757+
re.search(
758+
"already exists",
759+
result,
760+
)
761+
is not None
762+
), result
763+
assert re.search("Note: Resource added to", result) is not None

0 commit comments

Comments
 (0)