diff --git a/local-app/python-tools/sso-tools/README.md b/local-app/python-tools/sso-tools/README.md new file mode 100644 index 00000000..42edc0e8 --- /dev/null +++ b/local-app/python-tools/sso-tools/README.md @@ -0,0 +1,138 @@ +# sso-create-sc-group.py + +## Problem + +## Requirements + +* **Python 3.x** +* **Jinja2** library + +## Installation + +1. **Clone or copy** the script `sso-create-sc-group.py` to your working directory. +2. **Install Dependencies**: +```bash +pip install jinja2 + +``` + + +3. **Make Executable**: +```bash +chmod +x sso-create-sc-group.py + +``` + + +4. **Prepare Templates**: Ensure a directory named `TEMPLATE/` exists in the same folder as the script. + +## How It Works + +The script automates the creation of service control groups by processing a template directory and generating a new, standardized folder. + +### 1. Naming Convention + +The target directory name (`created_group`) is constructed as follows: + +* **Format**: `{business_label}-{application_label}-{group}` +* **Format (no app label)**: `{business_label}-{group}` +* **Case**: The `group` and the final `created_group` name are automatically converted to **lowercase**. + +### 2. File Processing Logic + +The script iterates through every file in the `TEMPLATE/` directory: + +* **Jinja2 Templates (`.j2`)**: Any file ending in `.j2` is rendered using the Jinja2 engine. The literal string `GROUP` in the filename is replaced by the `created_group` name. +* **Static Files**: All other files are copied directly into the new directory without modification. + +### 3. Template Variables + +The following variables are exposed to Jinja2 and can be used in your templates via `{{ variable_name }}`: + +| Variable | Description | +| --- | --- | +| `business_label` | The value provided via `-b` | +| `application_label` | The value provided via `-a` (if any) | +| `group` | The group name (provided via `-g` or the current folder name) | +| `created_group` | The final computed lowercase name of the directory | +| `description` | The text provided via `-d` | + +## Usage Examples + +**Basic Usage** (uses current directory name as group): + +```bash +./sso-create-sc-group.py -b fin -d "Financial audit logs" + +``` + +**Full Specification**: + +```bash +./sso-create-sc-group.py -b mkt -a email -g subscribers -d "Marketing email list" + +``` + +**Overwrite Existing**: + +```bash +./sso-create-sc-group.py -b fin -g audit -f + +``` + +## Template Variables + +You can now use these metadata variables in your templates (e.g., in a file header): + +| Variable | Description | +| --- | --- | +| `script_name` | The name of the script (`sso-create-sc-group.py`) | +| `version` | The current script version (e.g., `1.0.5`) | +| `created_time` | Timestamp of execution (`YYYY-MM-DD HH:MM:SS`) | + +**Example usage in `TEMPLATE/GROUP.tf.j2`:** + +```hcl +# Generated by {{ script_name }} v{{ version }} +# Created at: {{ created_time }} +# Description: {{ description }} + +resource "aws_identitystore_group" "this" { + display_name = "{{ created_group }}" +} + +``` + +## CHANGELOG + +### v1.0.5 + +* Added `script_name`, `version`, and `created_time` to the Jinja2 render context for better file auditing/header generation. + + +### v1.0.4 + +* Added `--description` (`-d`) argument and exposed it to Jinja2 context. +* Added a startup banner displaying the script name, version, and target group. + +### v1.0.3 + +* Added directory existence validation. +* Implemented `--force` (`-f`) flag to allow overwriting of existing directories. +* Added `sys.exit(1)` on errors for better CI/CD integration. + +### v1.0.2 + +* Enforced lowercase normalization for the `group` name and the final `created_group` name. + +### v1.0.1 + +* Added `#!/usr/bin/env python` shebang for direct execution. +* Exposed `business_label`, `application_label`, `group`, and `created_group` as variables to the Jinja2 engine. + +### v1.0.0 + +* Initial release. +* Basic CLI argument parsing (`-b`, `-a`, `-g`). +* Template rendering logic for `.j2` files and static file copying. + diff --git a/local-app/python-tools/sso-tools/sso-create-sc-group.py b/local-app/python-tools/sso-tools/sso-create-sc-group.py index b4854439..20ec1233 100755 --- a/local-app/python-tools/sso-tools/sso-create-sc-group.py +++ b/local-app/python-tools/sso-tools/sso-create-sc-group.py @@ -4,15 +4,13 @@ import sys import os from pathlib import Path +from datetime import datetime from jinja2 import Environment, FileSystemLoader # Version History: -# 1.0.0: Initial release -# 1.0.1: Added shebang, exposed variables to Jinja2 -# 1.0.2: Enforced lowercase for group and created_group names -# 1.0.3: Added directory existence check and --force flag -# 1.0.4: Added --description, startup banner, and context exposure -__version__ = "1.0.4" +# 1.0.0 - 1.0.4: Initial logic, lowercase enforcement, force flag, description +# 1.0.5: Added script_name, version, and created_time to Jinja2 context +__version__ = "1.0.5" def create_sc_group(): parser = argparse.ArgumentParser(description="Automate file creation from templates.") @@ -25,7 +23,11 @@ def create_sc_group(): args = parser.parse_args() - # 1. Determine names and force to lowercase + # 1. Setup metadata + script_name = os.path.basename(__file__) + now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + # 2. Determine names and force to lowercase raw_group = args.group if args.group else Path.cwd().name group_name = raw_group.lower() @@ -34,19 +36,18 @@ def create_sc_group(): else: created_group = f"{args.business_label}-{group_name}".lower() - # 2. Output Startup Banner - script_name = os.path.basename(__file__) + # 3. Output Startup Banner print(f"--- {script_name} v{__version__} ---") print(f"Targeting Group: {created_group}\n") - # 3. Check for existing directory + # 4. Check for existing directory target_dir = Path(created_group) if target_dir.exists() and not args.force: print(f"Error: Directory '{created_group}' already exists.") print("Use --force or -f to recreate the files.") sys.exit(1) - # 4. Setup template path + # 5. Setup template path template_dir = Path("TEMPLATE") if not template_dir.exists(): print(f"Error: {template_dir} directory not found.") @@ -54,19 +55,22 @@ def create_sc_group(): target_dir.mkdir(parents=True, exist_ok=True) - # 5. Initialize Jinja2 Environment + # 6. Initialize Jinja2 Environment env = Environment(loader=FileSystemLoader(str(template_dir))) - # 6. Context variables (Description exposed here) + # 7. Context variables (Now including script metadata) render_vars = { "business_label": args.business_label, "application_label": args.application_label, "group": group_name, "created_group": created_group, - "description": args.description or "" + "description": args.description or "", + "script_name": script_name, + "version": __version__, + "created_time": now } - # 7. Process files + # 8. Process files for item in template_dir.iterdir(): if item.is_dir(): continue