Skip to content

Commit

Permalink
restore headers
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Jan 2, 2026
1 parent a78bdc6 commit 5dbe950
Showing 1 changed file with 28 additions and 17 deletions.
45 changes: 28 additions & 17 deletions local-app/python-tools/cross-organization/org_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
def tqdm(iterable, **kwargs): return iterable

# --- VERSIONING ---
__version__ = "1.6.1"
__version__ = "1.6.2"

class OrgTaskRunner:
def __init__(self, args):
Expand All @@ -28,9 +28,6 @@ def __init__(self, args):
self.created_files = []
self.start_time = 0

def log_print(self, message=""):
self.output_log.append(message)

def get_ou_path(self, org_client, entity_id):
if entity_id in self.hierarchy_cache: return self.hierarchy_cache[entity_id]
if entity_id.startswith('r-'):
Expand Down Expand Up @@ -83,22 +80,35 @@ def process_account(self, acc, partition, tasks):
def run(self):
self.start_time = time.perf_counter()
session = boto3.Session(profile_name=self.args.profile, region_name=self.args.region)
org_client = session.client('organizations')
partition = session.client('sts').get_caller_identity()['Arn'].split(':')[1]

tasks, check_names = [], []
# Load tasks & build dynamic metadata
tasks, check_info = [], []
if self.args.enable_checks:
sys.path.append(os.getcwd())
for m in self.args.enable_checks:
module = importlib.import_module(m.replace('.py', ''))
mod_name = m.replace('.py', '')
module = importlib.import_module(mod_name)
tasks.append(getattr(module, 'account_task'))
check_names.append(m.replace('.py', ''))
v = getattr(module, '__version__', '?.?.?')
check_info.append(f"{mod_name} (v{v})")

all_accounts = [acc for page in session.client('organizations').get_paginator('list_accounts').paginate()
for acc in page['Accounts'] if acc['Status'] == 'ACTIVE']
check_suffix = ".".join([m.replace('.py', '') for m in (self.args.enable_checks or [])]) or "connectivity"

print("-" * 60)
print(f"AWS ORG TASK RUNNER - v{__version__} | Runners: {self.args.max_workers}")
print("-" * 60)
# Gather accounts and count them before processing
all_accounts = [acc for page in org_client.get_paginator('list_accounts').paginate()
for acc in page['Accounts'] if acc['Status'] == 'ACTIVE']
all_accounts.sort(key=lambda x: x['Name' if self.args.sort == 'name' else 'Id'].lower())

# RESTORED HEADER
print("-" * 100)
print(f"AWS ORG TASK RUNNER - v{__version__}")
print(f"Target Role: {self.args.role_name}")
print(f"Runners: {self.args.max_workers}")
print(f"Enabled Checks: {', '.join(check_info) if check_info else 'None'}")
print(f"Accounts Found: {len(all_accounts)}")
print("-" * 100)

with ThreadPoolExecutor(max_workers=self.args.max_workers) as executor:
futures = {executor.submit(self.process_account, acc, partition, tasks): acc for acc in all_accounts}
Expand All @@ -110,7 +120,8 @@ def run(self):

if self.args.output:
ds = datetime.now().strftime("%Y%m%dT%H%M%S")
# 1. ACCOUNT BASELINE (Metadata Only)

# 1. ACCOUNT BASELINE
acc_base = f"audit_results.account.{ds}"
with open(f"{acc_base}.json", 'w') as f: json.dump([r['metadata'] for r in self.full_results], f, indent=2)
with open(f"{acc_base}.csv", 'w', newline='') as f:
Expand All @@ -119,18 +130,18 @@ def run(self):
w.writerows([r['metadata'] for r in self.full_results])
self.created_files.extend([f"{acc_base}.json", f"{acc_base}.csv"])

# 2. CHECK SPECIFIC FILES (Data + Account Context)
for cn in check_names:
# 2. CHECK SPECIFIC FILES
for cn in [m.replace('.py', '') for m in (self.args.enable_checks or [])]:
chk_base = f"audit_results.{cn}.{ds}"
# Save CSV (Long Format)
# Save CSV
with open(f"{chk_base}.csv", 'w', newline='') as f:
w = csv.writer(f)
w.writerow(["account_id", "account_alias", "region", "field_name", "field_value"])
for res in self.full_results:
for reg, fields in res["checks"].items():
for k, v in fields.items():
w.writerow([res["metadata"]["account_id"], res["metadata"]["alias"], reg, k, v])
# Save JSON (Hierarchical)
# Save JSON
with open(f"{chk_base}.json", 'w') as f:
json.dump([{"account_id": r["metadata"]["account_id"], "alias": r["metadata"]["alias"], "data": r["checks"]} for r in self.full_results], f, indent=2)

Expand Down

0 comments on commit 5dbe950

Please sign in to comment.