mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 15:06:26 +02:00
Restructured CLI meta commands
This commit is contained in:
0
cli/meta/applications/__init__.py
Normal file
0
cli/meta/applications/__init__.py
Normal file
49
cli/meta/applications/all.py
Normal file
49
cli/meta/applications/all.py
Normal 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()
|
107
cli/meta/applications/in_group_deps.py
Normal file
107
cli/meta/applications/in_group_deps.py
Normal 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()
|
74
cli/meta/applications/role_name.py
Normal file
74
cli/meta/applications/role_name.py
Normal 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()
|
Reference in New Issue
Block a user