Restructured CLI meta commands

This commit is contained in:
2025-07-12 17:05:00 +02:00
parent 80ca12938b
commit 3eb8b54a1a
8 changed files with 16 additions and 6 deletions

View File

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env python3
import argparse
import glob
import os
import sys
try:
import yaml
except ImportError:
sys.stderr.write("PyYAML is required. Install with `pip install pyyaml`.\n")
sys.exit(1)
def find_application_ids():
"""
Searches all files matching roles/*/vars/main.yml for the key 'application_id'
and returns a list of all found IDs.
"""
pattern = os.path.join('roles', '*', 'vars', 'main.yml')
app_ids = []
for filepath in glob.glob(pattern):
try:
with open(filepath, 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
except Exception as e:
sys.stderr.write(f"Error reading {filepath}: {e}\n")
continue
if isinstance(data, dict) and 'application_id' in data:
app_ids.append(data['application_id'])
return sorted(set(app_ids))
def main():
parser = argparse.ArgumentParser(
description='Output a list of all application_id values defined in roles/*/vars/main.yml'
)
# No arguments other than --help
parser.parse_args()
ids = find_application_ids()
for app_id in ids:
print(app_id)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""
CLI wrapper for applications_if_group_and_deps filter.
"""
import argparse
import sys
import os
import yaml
from filter_plugins.applications_if_group_and_deps import FilterModule
def find_role_dirs_by_app_id(app_ids, roles_dir):
"""
Map application_ids to role directory names based on vars/main.yml in each role.
"""
mapping = {}
for role in os.listdir(roles_dir):
role_path = os.path.join(roles_dir, role)
vars_file = os.path.join(role_path, 'vars', 'main.yml')
if not os.path.isfile(vars_file):
continue
try:
with open(vars_file) as f:
data = yaml.safe_load(f) or {}
except Exception:
continue
app_id = data.get('application_id')
if isinstance(app_id, str) and app_id:
mapping[app_id] = role
# Translate each requested app_id to role dir if exists
dirs = []
for gid in app_ids:
if gid in mapping:
dirs.append(mapping[gid])
else:
# keep original if it matches a directory
if os.path.isdir(os.path.join(roles_dir, gid)):
dirs.append(gid)
return dirs
def main():
parser = argparse.ArgumentParser(
description="Filter applications by group names (role dirs or application_ids) and their recursive role dependencies."
)
parser.add_argument(
"-a", "--applications",
type=str,
required=True,
help="Path to YAML file defining the applications dict."
)
parser.add_argument(
"-g", "--groups",
nargs='+',
required=True,
help="List of group names to filter by (role directory names or application_ids)."
)
args = parser.parse_args()
# Load applications
try:
with open(args.applications) as f:
data = yaml.safe_load(f)
except Exception as e:
print(f"Error loading applications file: {e}", file=sys.stderr)
sys.exit(1)
# Unwrap under 'applications' key if present
if isinstance(data, dict) and 'applications' in data and isinstance(data['applications'], dict):
applications = data['applications']
else:
applications = data
if not isinstance(applications, dict):
print(
f"Expected applications YAML to contain a mapping (or 'applications' mapping), got {type(applications).__name__}",
file=sys.stderr
)
sys.exit(1)
# Determine roles_dir relative to project root
script_dir = os.path.dirname(__file__)
project_root = os.path.abspath(os.path.join(script_dir, '..', '..', '..'))
roles_dir = os.path.join(project_root, 'roles')
# Map user-provided groups (which may be application_ids) to role directory names
group_dirs = find_role_dirs_by_app_id(args.groups, roles_dir)
if not group_dirs:
print(f"No matching role directories found for groups: {args.groups}", file=sys.stderr)
sys.exit(1)
# Run filter using role directory names
try:
filtered = FilterModule().applications_if_group_and_deps(
applications,
group_dirs
)
except Exception as e:
print(f"Error running filter: {e}", file=sys.stderr)
sys.exit(1)
# Output result as YAML
print(yaml.safe_dump(filtered, default_flow_style=False))
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""
CLI Script: get_role_folder_cli.py
This script determines the appropriate Ansible role folder based on the provided application_id
by inspecting each role's vars/main.yml within the roles directory. By default, it assumes the
roles directory is located at the project root, relative to this script's location.
"""
import os
import sys
import argparse
import yaml
def get_role_folder(application_id, roles_path):
"""
Find the role directory under `roles_path` whose vars/main.yml contains the specified application_id.
:param application_id: The application_id to match.
:param roles_path: Path to the roles directory.
:return: The name of the matching role directory.
:raises RuntimeError: If no match is found or if an error occurs while reading files.
"""
if not os.path.isdir(roles_path):
raise RuntimeError(f"Roles path not found: {roles_path}")
for role in sorted(os.listdir(roles_path)):
role_dir = os.path.join(roles_path, role)
vars_file = os.path.join(role_dir, 'vars', 'main.yml')
if os.path.isfile(vars_file):
try:
with open(vars_file, 'r') as f:
data = yaml.safe_load(f) or {}
except Exception as e:
raise RuntimeError(f"Failed to load {vars_file}: {e}")
if data.get('application_id') == application_id:
return role
raise RuntimeError(f"No role found with application_id '{application_id}' in {roles_path}")
def main():
parser = argparse.ArgumentParser(
description='Determine the Ansible role folder by application_id'
)
parser.add_argument(
'application_id',
help='The application_id defined in vars/main.yml to search for'
)
parser.add_argument(
'-r', '--roles-path',
default=os.path.join(
os.path.dirname(os.path.realpath(__file__)),
os.pardir, os.pardir, os.pardir,
'roles'
),
help='Path to the roles directory (default: roles/ at project root)'
)
args = parser.parse_args()
try:
folder = get_role_folder(args.application_id, args.roles_path)
print(folder)
sys.exit(0)
except RuntimeError as err:
print(f"Error: {err}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()