Skip to content

Commit 301cae5

Browse files
authored
Add playbook argspec to init project scaffolding and as resource (#420)
* Add playbook argspec to init project scaffolding and as resource * Fixing file extension and adding test * Removing .j2 extension from files * Updating argspec definition and playbook as needed * Whoops, forgot to update test fixtures * Updating playbook and argspec files with additional metadata * Correcting filenames * Add more detail to playbook header comments
1 parent 6fce326 commit 301cae5

File tree

15 files changed

+455
-10
lines changed

15 files changed

+455
-10
lines changed

docs/installing.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,13 @@ $ ansible-creator add resource <resource-type> <path>
390390

391391
#### Positional Arguments
392392

393-
| Parameter | Description |
394-
| --------------------- | ---------------------------------------------------------------- |
395-
| devcontainer | Add devcontainer files to an existing Ansible project. |
396-
| devfile | Add a devfile file to an existing Ansible project. |
397-
| role | Add a role to an existing Ansible collection. |
398-
| execution-environment | Add a sample execution-environment.yml file to an existing path. |
393+
| Parameter | Description |
394+
| --------------------- | ------------------------------------------------------------------ |
395+
| devcontainer | Add devcontainer files to an existing Ansible project. |
396+
| devfile | Add a devfile file to an existing Ansible project. |
397+
| play-argspec | Add playbook argspec examples file to an existing Ansible project. |
398+
| role | Add a role to an existing Ansible collection. |
399+
| execution-environment | Add a sample execution-environment.yml file to an existing path. |
399400

400401
#### Example of adding a resource
401402

src/ansible_creator/arg_parser.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ def _add_resource(self, subparser: SubParser[ArgumentParser]) -> None:
211211
)
212212
self._add_resource_devcontainer(subparser=subparser)
213213
self._add_resource_devfile(subparser=subparser)
214+
self._add_resource_play_argspec(subparser=subparser)
214215
self._add_resource_role(subparser=subparser)
215216
self._add_resource_execution_env(subparser=subparser)
216217

@@ -268,6 +269,29 @@ def _add_resource_devfile(self, subparser: SubParser[ArgumentParser]) -> None:
268269
self._add_overwrite(parser)
269270
self._add_args_common(parser)
270271

272+
def _add_resource_play_argspec(self, subparser: SubParser[ArgumentParser]) -> None:
273+
"""Add example playbook argspec files to an existing Ansible project.
274+
275+
Args:
276+
subparser: The subparser to add playbook argspec files to
277+
"""
278+
parser = subparser.add_parser(
279+
"play-argspec",
280+
help="Add example playbook argspec files to an existing Ansible project.",
281+
formatter_class=CustomHelpFormatter,
282+
)
283+
284+
parser.add_argument(
285+
"path",
286+
default="./",
287+
metavar="path",
288+
help="The destination directory for the playbook argspec files. The default is the "
289+
"current working directory.",
290+
)
291+
292+
self._add_overwrite(parser)
293+
self._add_args_common(parser)
294+
271295
def _add_resource_role(self, subparser: SubParser[ArgumentParser]) -> None:
272296
"""Add a role to an existing Ansible collection.
273297
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Example play argspec file
2+
---
3+
short_description: A shorter summary of `description` below
4+
description: This is a description of a playbook, that may contain multiple plays with multiple play argument specs
5+
argument_specs:
6+
debug_localhost:
7+
short_description: Play for printing a debug message
8+
description:
9+
- Example play within a collection containing an argspec for printing a debug message
10+
author:
11+
- developer (@developer)
12+
options:
13+
message:
14+
description: Debug message to print
15+
type: str
16+
required: true
17+
examples: |
18+
- import_playbook: argspec_validation_plays.yml
19+
vars:
20+
message: 'Custom debug message'
21+
return: ~
22+
ping_localhost:
23+
short_description: Play for pinging localhost with custom data
24+
description:
25+
- Example play within a collection containing an argspec for pinging localhost with custom data
26+
author:
27+
- developer (@developer)
28+
options:
29+
ping_data:
30+
description: Ping data
31+
type: str
32+
required: true
33+
examples: |
34+
- import_playbook: argspec_validation_plays.yml
35+
vars:
36+
data: Pong
37+
return: ~
38+
set_stats:
39+
short_description: Play for setting a custom stat
40+
description:
41+
- Example play within a collection containing an argspec for setting a custom stat
42+
author:
43+
- developer (@developer)
44+
options:
45+
stat:
46+
description: Stat data
47+
type: raw
48+
required: true
49+
notes:
50+
- This play has some notes
51+
- They specify additional information
52+
examples: |
53+
- import_playbook: argspec_validation_plays.yml
54+
vars:
55+
stat: This is some custom stat
56+
return:
57+
stat:
58+
description: Custom stat data
59+
returned: always
60+
type: raw
61+
sample: Hello, World!
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Example playbook using play argspec validation
2+
# Run with:
3+
# ansible-playbook argspec_validation_plays.yml -e message=hello -i inventory/argspec_validation_inventory.yml
4+
---
5+
- name: Debug_localhost
6+
hosts: localhost
7+
gather_facts: false
8+
tasks:
9+
- name: Verify with argspec
10+
ansible.builtin.validate_argument_spec:
11+
argument_spec: "{{ (lookup('ansible.builtin.file', filename) | from_yaml)['argument_specs'][lowercase_play_name]['options'] }}"
12+
vars:
13+
lowercase_play_name: "{{ ansible_play_name | lower }}"
14+
filename: "argspec_validation_plays.meta.yml"
15+
- name: Print debug message
16+
ansible.builtin.debug:
17+
msg: "{{ message }}"
18+
19+
- name: Ping_localhost
20+
hosts: localhost
21+
gather_facts: false
22+
tasks:
23+
- name: Verify with argspec
24+
ansible.builtin.validate_argument_spec:
25+
argument_spec: "{{ (lookup('ansible.builtin.file', filename) | from_yaml)['argument_specs'][lowercase_play_name]['options'] }}"
26+
vars:
27+
lowercase_play_name: "{{ ansible_play_name | lower }}"
28+
filename: "argspec_validation_plays.meta.yml"
29+
- name: Print debug message
30+
ansible.builtin.ping:
31+
data: "{{ ping_data }}"
32+
33+
- name: Set_stats
34+
hosts: localhost
35+
gather_facts: false
36+
tasks:
37+
- name: Verify with argspec
38+
ansible.builtin.validate_argument_spec:
39+
argument_spec: "{{ (lookup('ansible.builtin.file', filename) | from_yaml)['argument_specs'][lowercase_play_name]['options'] }}"
40+
vars:
41+
lowercase_play_name: "{{ ansible_play_name | lower }}"
42+
filename: "argspec_validation_plays.meta.yml"
43+
- name: Set custom stats
44+
ansible.builtin.set_stats:
45+
data: "{{ stat }}"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
all:
3+
vars:
4+
ping_data: Pong
5+
stat:
6+
description: Custom stat data
7+
returned: always
8+
type: raw
9+
sample: Hello, World!

src/ansible_creator/resources/playbook_project/README.md.j2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ project requirements.
3030
| └── README.md
3131
| └── tasks/main.yml
3232
|── inventory/
33+
| |── hosts.yml
34+
| |── argspec_validation_inventory.yml
3335
| └── groups_vars/
3436
| └── host_vars/
35-
| └── hosts.yml
3637
|── ansible-navigator.yml
3738
|── ansible.cfg
3839
|── devfile.yaml
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Example play argspec file
2+
---
3+
short_description: A shorter summary of `description` below
4+
description: This is a description of a playbook, that may contain multiple plays with multiple play argument specs
5+
argument_specs:
6+
debug_localhost:
7+
short_description: Play for printing a debug message
8+
description:
9+
- Example play within a collection containing an argspec for printing a debug message
10+
author:
11+
- developer (@developer)
12+
options:
13+
message:
14+
description: Debug message to print
15+
type: str
16+
required: true
17+
examples: |
18+
- import_playbook: argspec_validation_plays.yml
19+
vars:
20+
message: 'Custom debug message'
21+
return: ~
22+
ping_localhost:
23+
short_description: Play for pinging localhost with custom data
24+
description:
25+
- Example play within a collection containing an argspec for pinging localhost with custom data
26+
author:
27+
- developer (@developer)
28+
options:
29+
ping_data:
30+
description: Ping data
31+
type: str
32+
required: true
33+
examples: |
34+
- import_playbook: argspec_validation_plays.yml
35+
vars:
36+
data: Pong
37+
return: ~
38+
set_stats:
39+
short_description: Play for setting a custom stat
40+
description:
41+
- Example play within a collection containing an argspec for setting a custom stat
42+
author:
43+
- developer (@developer)
44+
options:
45+
stat:
46+
description: Stat data
47+
type: raw
48+
required: true
49+
notes:
50+
- This play has some notes
51+
- They specify additional information
52+
examples: |
53+
- import_playbook: argspec_validation_plays.yml
54+
vars:
55+
stat: This is some custom stat
56+
return:
57+
stat:
58+
description: Custom stat data
59+
returned: always
60+
type: raw
61+
sample: Hello, World!
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Example playbook using play argspec validation
2+
# Run with:
3+
# ansible-playbook argspec_validation_plays.yml -e message=hello -i inventory/argspec_validation_inventory.yml
4+
---
5+
- name: Debug_localhost
6+
hosts: localhost
7+
gather_facts: false
8+
tasks:
9+
- name: Verify with argspec
10+
ansible.builtin.validate_argument_spec:
11+
argument_spec: "{{ (lookup('ansible.builtin.file', filename) | from_yaml)['argument_specs'][lowercase_play_name]['options'] }}"
12+
vars:
13+
lowercase_play_name: "{{ ansible_play_name | lower }}"
14+
filename: "argspec_validation_plays.meta.yml"
15+
- name: Print debug message
16+
ansible.builtin.debug:
17+
msg: "{{ message }}"
18+
19+
- name: Ping_localhost
20+
hosts: localhost
21+
gather_facts: false
22+
tasks:
23+
- name: Verify with argspec
24+
ansible.builtin.validate_argument_spec:
25+
argument_spec: "{{ (lookup('ansible.builtin.file', filename) | from_yaml)['argument_specs'][lowercase_play_name]['options'] }}"
26+
vars:
27+
lowercase_play_name: "{{ ansible_play_name | lower }}"
28+
filename: "argspec_validation_plays.meta.yml"
29+
- name: Print debug message
30+
ansible.builtin.ping:
31+
data: "{{ ping_data }}"
32+
33+
- name: Set_stats
34+
hosts: localhost
35+
gather_facts: false
36+
tasks:
37+
- name: Verify with argspec
38+
ansible.builtin.validate_argument_spec:
39+
argument_spec: "{{ (lookup('ansible.builtin.file', filename) | from_yaml)['argument_specs'][lowercase_play_name]['options'] }}"
40+
vars:
41+
lowercase_play_name: "{{ ansible_play_name | lower }}"
42+
filename: "argspec_validation_plays.meta.yml"
43+
- name: Set custom stats
44+
ansible.builtin.set_stats:
45+
data: "{{ stat }}"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
all:
3+
vars:
4+
ping_data: Pong
5+
stat:
6+
description: Custom stat data
7+
returned: always
8+
type: raw
9+
sample: Hello, World!

src/ansible_creator/subcommands/add.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ def _resource_scaffold(self) -> None:
163163
template_data = self._get_devcontainer_template_data()
164164
elif self._resource_type == "execution-environment":
165165
template_data = self._get_ee_template_data()
166+
elif self._resource_type == "play-argspec":
167+
template_data = self._get_play_argspec_template_data()
166168
elif self._resource_type == "role":
167169
self._check_collection_path()
168170
self._namespace, self._collection_name = self.role_galaxy()
@@ -414,10 +416,21 @@ def _get_plugin_template_data(self) -> TemplateData:
414416
)
415417

416418
def _get_ee_template_data(self) -> TemplateData:
417-
"""Get the template data for plugin.
419+
"""Get the template data for ee resources.
418420
419421
Returns:
420-
TemplateData: Data required for templating the plugin.
422+
TemplateData: Data required for templating the ee resources.
423+
"""
424+
return TemplateData(
425+
resource_type=self._resource_type,
426+
creator_version=self._creator_version,
427+
)
428+
429+
def _get_play_argspec_template_data(self) -> TemplateData:
430+
"""Get the template data for playbook argspec resources.
431+
432+
Returns:
433+
TemplateData: Data required for templating the playbook argspec resources.
421434
"""
422435
return TemplateData(
423436
resource_type=self._resource_type,

tests/fixtures/project/playbook_project/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ project requirements.
3030
| └── README.md
3131
| └── tasks/main.yml
3232
|── inventory/
33+
| |── hosts.yml
34+
| |── argspec_validation_inventory.yml
3335
| └── groups_vars/
3436
| └── host_vars/
35-
| └── hosts.yml
3637
|── ansible-navigator.yml
3738
|── ansible.cfg
3839
|── devfile.yaml

0 commit comments

Comments
 (0)