How roles are organized
Roles in TOPSAIL are standard Ansible roles that are wired into the
run_toolbox.py
command line interface.
In TOPSAIL, the roles are organized by projects, in the
projects/PROJECT_NAME/roles
directories. Their structure follows
Ansible standard role guidelines:
toolbox/
├── <group name>.py
└── <new_role_name>/
├── defaults
│ └── main.yml
├── files
│ └── .keep
├── README.md
├── tasks
│ └── main.yml
├── templates
│ └── example.yml.j2
└── vars
└── main.yml
How default parameters are generated
Topsail generates automatically all the default parameters in the
<role>/defaults/main.yml
file, to make sure all the roles
parameters are consistent with what the CLI supports
(run_toolbox.py
). The file <role>/defaults/main.yml
is
rendered automatically when executing from the project’s root folder:
./run_toolbox.py repo generate_toolbox_related_files
# or
./run_toolbox.py repo generate_ansible_default_settings
Including new roles in Topsail’s CLI
1. Creating a Python class for the new role
Create a class file to reference the new role and define the default parameters that can be referenced from the CLI as parameters.
In the project’s toolbox
directory, create or edit the
<project_name>.py
file with the following code:
import sys
from projects.core.library.ansible_toolbox import (
RunAnsibleRole, AnsibleRole,
AnsibleMappedParams, AnsibleConstant,
AnsibleSkipConfigGeneration
)
class <project_name>:
"""
Commands relating to <project_name>
"""
@AnsibleRole("<new_role_name>")
@AnsibleMappedParams
def run(self,
<new_role_parameter_1>,
<new_role_parameter_n>,
):
"""
Run <new_role_name>
Args:
<new_role_parameter_1>: First parameter
<new_role_parameter_n>: Nth parameter
"""
# if needed, perform simple parameters validation here
return RunAnsibleRole(locals())
Description of the decorators
@AnsibleROle(role_name)
tells the role where the command is implemented@AnsibleMappedParams
specifies that the Python arguments should be mapped into the Ansible arguments (that’s the most common)@AnsibleSkipConfigGeneration
specifies that no configuration should be generated for this command (usually, it means that another command already specifies the arguments, and this one reuses the same role with different settings)@AnsibleConstant(description, name, value)
specifies a Ansible argument without Python equivalent. Can be used to pass flags embedded in the function name. Eg:dump_prometheus
andreset_prometheus
.
2. Including the new toolbox class in the Toolbox
This step in not necessary anymore. The run_toolbox.py
command
from the root directory loads the toolbox with this generic call:
projects.core.library.ansible_toolbox.Toolbox()
This class traverses all the projects/*/toolbox/*.py
Python files,
and loads the class with the titled name of the file (simplified code):
for toolbox_file in (TOPSAIL_DIR / "projects").glob("*/toolbox/*.py"):
toolbox_module = __import__(toolbox_file)
toolbox_name = name of <toolbox_file> without extension
toolbox_class = getattr(toolbox_module, toolbox_name.title())
3. Rendering the default parameters
Now, once the new toolbox command is created, the role class is added to the
project’s root folder and the CLI entrypoint is included in the
Toolbox
class, it is possible to render the role default parameters
from the run_toolbox.py
CLI. To render the default parameters for
all roles execute:
./run_toolbox.py repo generate_ansible_default_settings
TOPSAIL GitHub repository will refuse to merge the PR if this command has not been called after the Python entrypoint has been modified.
4. Executing the new toolbox command
Once the role is in the correct folder and the Toolbox
entrypoints
are up to date, this new role can be executed directly from run_toolbox.py
like:
./run_toolbox.py <project_name> <new_role_name> <new_role_parameter_1> <new_role_parameter_n>