Skip to content

Commit b15da9b

Browse files
kaushiki069pre-commit-ci[bot]tanwigeetika1618
authored
Role addition using add subcommand (#391)
* adding files * test case addition * chore: auto fixes from pre-commit.com hooks * fixing test case * fix in test case * changing file * chore: auto fixes from pre-commit.com hooks * fix path in test case * fix file * chore: auto fixes from pre-commit.com hooks * removed file form fixture * adding file * chore: auto fixes from pre-commit.com hooks * fix * chore: auto fixes from pre-commit.com hooks * fix * chore: auto fixes from pre-commit.com hooks * fixes * commenting out test case for coming soon * chore: auto fixes from pre-commit.com hooks * remove coming soon test case * removing coming soon * adding back * adding back coming soon test to keep coverage intact * chore: auto fixes from pre-commit.com hooks * fixing test case for coming soon * chore: auto fixes from pre-commit.com hooks * fix * fixing name * chore: auto fixes from pre-commit.com hooks * adding name for role * chore: auto fixes from pre-commit.com hooks * fix docstring * test fixes * fixing path * added fixes for lint * fix lint * removing coming soon var * chore: auto fixes from pre-commit.com hooks * remove var coming soon * fixed version * removing unused code for lint fix * fixing folder structure * fixture fix * fix * chore: auto fixes from pre-commit.com hooks * fixed test case to remove re * adding files to fixture * fixes * chore: auto fixes from pre-commit.com hooks * add test cases * fixing help * comment fix * fixing fixtures * added changes for checking path * changes as per new review * fixes for review * adding task example * readme updates * added argument_specs file * remove fix * test --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: tanwigeetika1618 <[email protected]>
1 parent 71e054a commit b15da9b

File tree

37 files changed

+447
-64
lines changed

37 files changed

+447
-64
lines changed

.config/dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ testns
4343
testorg
4444
testpaths
4545
webservers
46+
role

.config/pydoclint-baseline.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ tests/units/test_basic.py
5050
DOC502: Function `test_not_a_tty` has a "Raises" section in the docstring, but there are not "raise" statements in the body
5151
DOC502: Function `test_main` has a "Raises" section in the docstring, but there are not "raise" statements in the body
5252
DOC502: Function `test_proj_main` has a "Raises" section in the docstring, but there are not "raise" statements in the body
53-
DOC502: Function `test_coming_soon` has a "Raises" section in the docstring, but there are not "raise" statements in the body
5453
DOC502: Function `test_config_post_init` has a "Raises" section in the docstring, but there are not "raise" statements in the body
5554
--------------------
5655
tests/units/test_compat.py

src/ansible_creator/arg_parser.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import argparse
6-
import contextlib
76
import re
87
import sys
98

@@ -34,8 +33,6 @@
3433

3534
MIN_COLLECTION_NAME_LEN = 2
3635

37-
COMING_SOON = ("add resource role",)
38-
3936

4037
class Parser:
4138
"""A parser for the command line arguments."""
@@ -81,21 +78,6 @@ def parse_args(self) -> tuple[argparse.Namespace, list[Msg]]:
8178
argcomplete.autocomplete(parser)
8279
self.args = parser.parse_args()
8380

84-
combinations = (
85-
("subcommand", "type", "resource_type"),
86-
("subcommand", "type", "plugin_type"),
87-
("subcommand", "project"),
88-
)
89-
for combination in combinations:
90-
with contextlib.suppress(AttributeError):
91-
name = " ".join(getattr(self.args, part) for part in combination)
92-
93-
if name in COMING_SOON:
94-
msg = f"The `{name}` command is coming soon. Please try in the next release."
95-
self.pending_logs.append(Msg(prefix=Level.HINT, message=msg))
96-
self.pending_logs.append(Msg(prefix=Level.CRITICAL, message="Goodbye."))
97-
return self.args, self.pending_logs
98-
9981
return self.args, self.pending_logs
10082

10183
def _add(self, subparser: SubParser[ArgumentParser]) -> None:
@@ -308,6 +290,8 @@ def _add_resource_role(self, subparser: SubParser[ArgumentParser]) -> None:
308290
help="The path to the Ansible collection. The default is the "
309291
"current working directory.",
310292
)
293+
294+
self._add_overwrite(parser)
311295
self._add_args_common(parser)
312296

313297
def _add_resource_execution_env(self, subparser: SubParser[ArgumentParser]) -> None:

src/ansible_creator/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Config:
3636
type: The type of the project for which the resource is being scaffolded.
3737
path: The file path where the resource should be added.
3838
image: The image to be used while scaffolding devcontainer.
39+
role_name: The role to be scaffolded.
3940
"""
4041

4142
creator_version: str
@@ -55,6 +56,7 @@ class Config:
5556
type: str = ""
5657
path: str | Path = "./"
5758
image: str = ""
59+
role_name: str = "run"
5860

5961
def __post_init__(self) -> None:
6062
"""Post process config values."""
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{{ namespace }}.{{ collection_name }} {{ role_name }} Role
2+
========================
3+
4+
A brief description of the role goes here.
5+
6+
Requirements
7+
------------
8+
9+
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
10+
11+
Role Variables
12+
--------------
13+
14+
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
15+
16+
Dependencies
17+
------------
18+
19+
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
20+
21+
Example Playbook
22+
----------------
23+
24+
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
25+
26+
```yaml
27+
- name: Execute tasks on servers
28+
hosts: servers
29+
roles:
30+
- role: {{ namespace }}.{{ collection_name }}.run
31+
run_x: 42
32+
```
33+
34+
Another way to consume this role would be:
35+
36+
```yaml
37+
- name: Initialize the run role from {{ namespace }}.{{ collection_name }}
38+
hosts: servers
39+
gather_facts: false
40+
tasks:
41+
- name: Trigger invocation of run role
42+
ansible.builtin.include_role:
43+
name: {{ namespace }}.{{ collection_name }}.run
44+
vars:
45+
run_x: 42
46+
```
47+
48+
Role Idempotency
49+
----------------
50+
51+
Designation of the role as idempotent (True/False)
52+
53+
Role Atomicity
54+
----------------
55+
56+
Designation of the role as atomic if applicable (True/False)
57+
58+
Roll-back capabilities
59+
----------------------
60+
61+
Define the roll-back capabilities of the role
62+
63+
Argument Specification
64+
----------------------
65+
66+
Including an example of how to add an argument Specification file that validates the arguments provided to the role.
67+
68+
```
69+
argument_specs:
70+
main:
71+
short_description: Role description.
72+
options:
73+
string_arg1:
74+
description: string argument description.
75+
type: "str"
76+
default: "x"
77+
choices: ["x", "y"]
78+
```
79+
80+
License
81+
-------
82+
83+
# TO-DO: Update the license to the one you want to use (delete this line after setting the license)
84+
BSD
85+
86+
Author Information
87+
------------------
88+
89+
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
# defaults file for {{ namespace }}.{{ collection_name }}.{{ role_name }}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
# handlers file for {{ namespace }}.{{ collection_name }}.{{ role_name }}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
# argument spec file for {{ namespace }}.{{ collection_name }}.{{ role_name }}
3+
4+
argument_specs:
5+
main:
6+
short_description: Role description.
7+
options:
8+
my_variable:
9+
type: str
10+
description: A simple string argument for demonstration.
11+
default: "default_value"

src/ansible_creator/resources/collection_project/roles/run/meta/main.yml.j2 renamed to src/ansible_creator/resources/common/role/roles/run/meta/main.yml.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
galaxy_info:
22
author: foo
3-
description: {{ namespace|capitalize }}.{{ collection_name|capitalize }} Run Role
4-
company: {{ namespace | capitalize }}
3+
description: {{ namespace }}.{{ collection_name }} {{ role_name }} Role
4+
company: {{ namespace }}
55

66
# If the issue tracker for your role is not on github, uncomment the
77
# next line and provide a value
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
# tasks file for {{ namespace }}.{{ collection_name }}.{{ role_name }}
3+
4+
# task example for debugging a value
5+
- name: Debug the value of my_variable
6+
ansible.builtin.debug:
7+
msg: "The value of my_variable is {% raw %}{{ my_variable }}{% endraw %}"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
# vars file for {{ namespace }}.{{ collection_name }}.{{ role_name }}

src/ansible_creator/subcommands/add.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def __init__(
3434
config: App configuration object.
3535
"""
3636
self._resource_type: str = config.resource_type
37+
self._role_name: str = config.role_name
3738
self._plugin_type: str = config.plugin_type
3839
self._resource_id: str = f"common.{self._resource_type}"
3940
self._plugin_id: str = f"collection_project.plugins.{self._plugin_type}"
@@ -47,6 +48,8 @@ def __init__(
4748
self._dev_container_image = config.image
4849
self.output: Output = config.output
4950
self.templar = Templar()
51+
self._namespace: str = config.namespace or ""
52+
self._collection_name: str = config.collection_name or ""
5053

5154
@property
5255
def _plugin_type_output(self) -> str:
@@ -140,6 +143,10 @@ def _resource_scaffold(self) -> None:
140143
template_data = self._get_devcontainer_template_data()
141144
elif self._resource_type == "execution-environment":
142145
template_data = self._get_ee_template_data()
146+
elif self._resource_type == "role":
147+
self._check_collection_path()
148+
self._namespace, self._collection_name = self.role_galaxy()
149+
template_data = self._get_role_template_data()
143150
else:
144151
msg = f"Unsupported resource type: {self._resource_type}"
145152
raise CreatorError(msg)
@@ -396,3 +403,43 @@ def _get_ee_template_data(self) -> TemplateData:
396403
resource_type=self._resource_type,
397404
creator_version=self._creator_version,
398405
)
406+
407+
def role_galaxy(self) -> tuple[str, str]:
408+
"""Fetch values from galaxy.yml file.
409+
410+
Returns:
411+
tuple[str, str]: A tuple containing the namespace and collection name.
412+
Defaults are ('your-collection-namespace', 'your-collection-name')
413+
if the file is missing or keys are absent.
414+
"""
415+
fallback_cn = "your-collection-namespace"
416+
fallback_ns = "your-collection-name"
417+
galaxy_file = self._add_path / "galaxy.yml"
418+
419+
# Check if galaxy.yml exists
420+
if not galaxy_file.exists():
421+
return fallback_cn, fallback_ns
422+
423+
# Load the galaxy.yml file
424+
with galaxy_file.open("r", encoding="utf-8") as file:
425+
data = yaml.safe_load(file)
426+
427+
# Ensure the namespace and name key exists
428+
namespace = data.get("namespace", "your-collection-namespace")
429+
collection_name = data.get("name", "your-collection-name")
430+
431+
return namespace, collection_name
432+
433+
def _get_role_template_data(self) -> TemplateData:
434+
"""Get the template data for role resources.
435+
436+
Returns:
437+
TemplateData: Data required for templating the role resource.
438+
"""
439+
return TemplateData(
440+
resource_type=self._resource_type,
441+
role_name=self._role_name,
442+
namespace=self._namespace,
443+
collection_name=self._collection_name,
444+
creator_version=self._creator_version,
445+
)

src/ansible_creator/subcommands/init.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Init:
2626
common_resources: List of common resources to copy.
2727
"""
2828

29-
common_resources = (
29+
common_resources: tuple[str, ...] = (
3030
"common.devcontainer",
3131
"common.devfile",
3232
"common.gitignore",
@@ -52,6 +52,7 @@ def __init__(
5252
self._project = config.project
5353
self._templar = Templar()
5454
self.output: Output = config.output
55+
self._role_name: str = config.role_name
5556

5657
def run(self) -> None:
5758
"""Start scaffolding skeleton."""
@@ -128,10 +129,14 @@ def _scaffold(self) -> None:
128129
collection_name=self._collection_name,
129130
creator_version=self._creator_version,
130131
dev_file_name=self.unique_name_in_devfile(),
132+
role_name=self._role_name,
131133
)
132134

133135
if self._project == "execution_env":
134136
resources = (f"{self._project}_project",)
137+
elif self._project == "collection":
138+
self.common_resources = (*self.common_resources, "common.role")
139+
resources = (f"{self._project}_project", *self.common_resources)
135140
else:
136141
resources = (f"{self._project}_project", *self.common_resources)
137142

src/ansible_creator/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class TemplateData:
2020
resource_type: The type of resource to be scaffolded.
2121
plugin_type: The type of plugin to be scaffolded.
2222
plugin_name: The name of the plugin to be scaffolded.
23+
role_name: The name of the role to be scaffolded.
2324
additions: A dictionary containing additional data to add to the gitignore.
2425
collection_name: The name of the collection.
2526
creator_version: The version of the creator.
@@ -34,6 +35,7 @@ class TemplateData:
3435
resource_type: str = ""
3536
plugin_type: str = ""
3637
plugin_name: str = ""
38+
role_name: str = ""
3739
additions: dict[str, dict[str, dict[str, str | bool]]] = field(default_factory=dict)
3840
collection_name: str = ""
3941
creator_version: str = ""

src/ansible_creator/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"sample_filter": "plugin_name",
3434
"sample_lookup": "plugin_name",
3535
"sample_test": "plugin_name",
36+
"run": "role_name",
3637
}
3738

3839

tests/fixtures/collection/testorg/testcol/roles/run/README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Testorg.Testcol Run Role
1+
testorg.testcol run Role
22
========================
33

44
A brief description of the role goes here.
@@ -45,6 +45,38 @@ Another way to consume this role would be:
4545
run_x: 42
4646
```
4747
48+
Role Idempotency
49+
----------------
50+
51+
Designation of the role as idempotent (True/False)
52+
53+
Role Atomicity
54+
----------------
55+
56+
Designation of the role as atomic if applicable (True/False)
57+
58+
Roll-back capabilities
59+
----------------------
60+
61+
Define the roll-back capabilities of the role
62+
63+
Argument Specification
64+
----------------------
65+
66+
Including an example of how to add an argument Specification file that validates the arguments provided to the role.
67+
68+
```
69+
argument_specs:
70+
main:
71+
short_description: Role description.
72+
options:
73+
string_arg1:
74+
description: string argument description.
75+
type: "str"
76+
default: "x"
77+
choices: ["x", "y"]
78+
```
79+
4880
License
4981
-------
5082
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
# defaults file for run
2+
# defaults file for testorg.testcol.run
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
# handlers file for run
2+
# handlers file for testorg.testcol.run
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
# argument spec file for testorg.testcol.run
3+
4+
argument_specs:
5+
main:
6+
short_description: Role description.
7+
options:
8+
my_variable:
9+
type: str
10+
description: A simple string argument for demonstration.
11+
default: "default_value"

0 commit comments

Comments
 (0)