diff --git a/local-app/python-tools/cross-organization/org_runner3.py b/local-app/python-tools/cross-organization/org_runner3.py index 0a1121b5..3ad22051 100755 --- a/local-app/python-tools/cross-organization/org_runner3.py +++ b/local-app/python-tools/cross-organization/org_runner3.py @@ -20,7 +20,7 @@ from rich.progress import Progress, BarColumn, TextColumn, TimeElapsedColumn, SpinnerColumn # --- VERSIONING --- -__version__ = "3.3.1" +__version__ = "3.3.2" console = Console() @@ -34,20 +34,13 @@ def __init__(self, console_stream, filepath): self.console = console_stream self.log_file = open(filepath, "a", encoding="utf-8", buffering=1) self.lock = threading.Lock() - # Regex pattern targeting standard ANSI escape color/style matrices self.ansi_color_regex = re.compile(r'\x1b\[[0-9;]*[mK]') def write(self, message): - # Always output the raw colored text directly to the console screen self.console.write(message) - - # Discard lines that do carriage returns or cursor movements (Progress Bars / Live Views) if "\r" in message or "\x1b[A" in message or "\x1b[2K" in message: return - - # Clean the message by removing ANSI color codes for file persistence clean_message = self.ansi_color_regex.sub('', message) - if clean_message: with self.lock: self.log_file.write(clean_message) @@ -132,7 +125,6 @@ def build_assumed_role_session(base_session, target_account_id, role_name, regio def execute_module_task(mod_entry_hook, base_session, acct_meta, target_regions, cli_args, progress_queue, task_index): """Executes the module task and injects full execution, version, and credentials telemetry.""" acct_id = acct_meta["account_id"] - acct_alias = acct_meta["alias"] primary_region = target_regions[0] def update_status_callback(test_label, total_count): @@ -169,7 +161,7 @@ def update_status_callback(test_label, total_count): "status_callback": update_status_callback, "account_session": delegated_session, "account_id": acct_id, - "account_name": acct_alias, + "account_name": acct_meta["alias"], "region": primary_region, "enable_checks": cli_args.enable_checks, "remediate": cli_args.remediate, @@ -215,7 +207,6 @@ def main(): parser.add_argument("--max-workers", type=int, default=4, help="Maximum concurrent worker channels") parser.add_argument("--profile", help="AWS configuration profile handle") parser.add_argument("--sort", help="Ordering criteria parameters") - parser.add_argument("--region", help="Single region parameter configuration mapping fallback") parser.add_argument("--regions", nargs="+", help="Space or comma-separated target regions list") @@ -224,22 +215,11 @@ def main(): group.add_argument("--progress-account", action="store_true", default=True, help="Spin up dynamic parallel swim lanes") parser.add_argument("--filter-accounts", help="Regex criteria applied against targets alias descriptors") - parser.add_argument( - "--logfile", - nargs="?", - const="DEFAULT_GENERATED", - default="DEFAULT_GENERATED", - help="Capture output to an operational log asset file (Optional custom path handle)" - ) - parser.add_argument( - "--no-logfile", - action="store_true", - help="Explicitly disable writing execution stream footprints out to standard disk logs" - ) + parser.add_argument("--logfile", nargs="?", const="DEFAULT_GENERATED", default="DEFAULT_GENERATED", help="Capture output to an log file") + parser.add_argument("--no-logfile", action="store_true", help="Explicitly disable logging output stream") args = parser.parse_args() - # --- LOGGING SYSTEM FRAMEWORK INITIALIZATION HOOK --- active_logger_handle = None if not args.no_logfile: log_path = args.logfile @@ -252,7 +232,6 @@ def main(): active_logger_handle = DualFrameworkLogger(sys.stdout, log_path) sys.stdout = active_logger_handle sys.stderr = DualFrameworkLogger(sys.stderr, log_path) - console.print(f"[*] Native audit log tracing activated dynamically out to: [white]{log_path}[/white]") command_line_string = " ".join(sys.argv) @@ -398,8 +377,13 @@ def main(): t_id = lane_task_ids[lane_id] total_t = int(signal["total_tests"]) if str(signal["total_tests"]).isdigit() else 45 - current_val = int(str(signal["current_test"]).split("-")[-1]) if "-" in str(signal["current_test"]) else 1 + + # --- FIXED: Robust regular expression integer search to parse indices from any separator pattern --- + found_digits = re.findall(r'\d+', str(signal["current_test"])) + current_val = int(found_digits[0]) if found_digits else 1 + pct_normalized = int((current_val / total_t) * 100) if total_t > 0 else 0 + if pct_normalized > 100: pct_normalized = 100 lane_progress.update( t_id, @@ -432,7 +416,7 @@ def main(): current_test="IDLE", total_tests="0" ) - time.sleep(0.1) + time.sleep(0.05) # Optimized sleep cycle for faster lane response intervals else: with Progress( SpinnerColumn(), @@ -496,7 +480,7 @@ def main(): hours, remainder = divmod(int(elapsed_duration), 3600) minutes, seconds = divmod(remainder, 60) - elapsed_friendly = f"{hours:02d}h:{minutes:02d}m:{seconds:02d}s" + elapsed_friendly = f"{hours:02d}h:{minutes:02dm}:{seconds:02d}s" console.print(f"[bold blue]----------------------------------------------------------------------[/bold blue]") console.print(f"Execution Timeline Status Summary Parameters:")