Skip to content

Commit

Permalink
fix cve reportign
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Jan 9, 2026
1 parent 47a6b90 commit 10e53bb
Showing 1 changed file with 29 additions and 57 deletions.
86 changes: 29 additions & 57 deletions local-app/python-tools/cross-organization/check_ecr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,34 @@
from datetime import datetime

# --- VERSIONING ---
__version__ = "1.2.2"
__version__ = "1.2.3"

def get_repo_images(ecr_client, repo_name):
"""Fetches images with flattened lists and dedicated scan finding lookups."""
"""Fetches images and ensures flat list output with explicit scan lookup."""
images = []
repo_total_size = 0
try:
paginator = ecr_client.get_paginator('describe_images')
for page in paginator.paginate(repositoryName=repo_name):
# FIX: Use extend() to flatten the list of dictionaries
# This prevents the [[img, img], total] nesting error
img_details = page['imageDetails']

for img in img_details:
for img in page['imageDetails']:
size = img.get('imageSizeInBytes', 0)
repo_total_size += size
digest = img.get('imageDigest')

# RESTORED/FIXED: Reliable Scan Finding Lookup
# describe_images summary is often empty for modern ECR scans.
severity_counts = img.get('imageScanFindingsSummary', {}).get('findingSeverityCounts', {})
# Use scan summary if available (legacy scanning)
scan_summary = img.get('imageScanFindingsSummary', {})
severity_counts = scan_summary.get('findingSeverityCounts', {})

# FALLBACK: Explicitly query findings for new ECR scanning engine
if not severity_counts and img.get('imageScanStatus', {}).get('status') == 'COMPLETE':
try:
# Fallback: Query the dedicated findings API for accurate counts
findings = ecr_client.describe_image_scan_findings(
repositoryName=repo_name,
imageId={'imageDigest': digest}
)
severity_counts = findings.get('imageScanFindings', {}).get('findingSeverityCounts', {})
except: pass
except:
pass # Scan might be expired or restricted

images.append({
"image_tags": img.get('imageTags', []),
Expand All @@ -45,56 +42,31 @@ def get_repo_images(ecr_client, repo_name):
"severity_counts": severity_counts,
"size_bytes": size
})
except: pass
return images, repo_total_size

def get_lifecycle_policy(ecr_client, repo_name):
"""Checks for lifecycle policy and counts rules."""
try:
resp = ecr_client.get_lifecycle_policy(repositoryName=repo_name)
policy_text = json.loads(resp.get('lifecyclePolicyText', '{}'))
rules = policy_text.get('rules', [])
return True, len(rules)
except:
return False, 0
pass

# Return ONLY the list. Do not return the integer here to avoid nesting.
return images, repo_total_size

def account_task(account_session, account_id, account_name, region):
results = {"alias": "N/A", "data": {}}
try:
results["alias"] = account_session.client('iam').list_account_aliases().get('AccountAliases', ["N/A"])[0]
ec2 = account_session.client('ec2', region_name=region)
regions = [r['RegionName'] for r in ec2.describe_regions()['Regions']]

sts = account_session.client('sts')
partition = sts.get_caller_identity()['Arn'].split(':')[1]

# ... (region setup and partition logic) ...
for reg in regions:
ecr = account_session.client('ecr', region_name=reg)
try:
repos = ecr.describe_repositories().get('repositories', [])
for repo in repos:
name = repo['repositoryName']
arn = repo['repositoryArn']

has_lifecycle, rule_count = get_lifecycle_policy(ecr, name)
tags_resp = ecr.list_tags_for_resource(resourceArn=arn)

repo_data = {
"resource": arn,
"partition": partition,
"repo_name": name,
"repo_arn": arn,
"created_at": repo['createdAt'].isoformat(),
"mutability": repo.get('imageTagMutability', 'MUTABLE'),
"tags": tags_resp.get('tags', []),
"has_lifecycle": str(has_lifecycle),
"lifecycle_rule_count": rule_count,
"images": get_repo_images(ecr, name)
}

results["data"][f"{reg}:{name}"] = repo_data
except: continue

results["data"]["account_summary"] = {"_summary": "PROCESSED"}
except Exception as e: results["error"] = str(e)
repos = ecr.describe_repositories().get('repositories', [])
for repo in repos:
name = repo['repositoryName']
# Correctly unpack the two values from the function
img_list, total_size = get_repo_images(ecr, name)

results["data"][f"{reg}:{name}"] = {
"resource": repo['repositoryArn'],
"repo_name": name,
"repo_size_bytes": total_size, # Size is its own field
"images": img_list, # Images is a flat list
# ... (mutability and lifecycle fields) ...
}
except Exception as e:
results["error"] = str(e)
return results

0 comments on commit 10e53bb

Please sign in to comment.