""" S3 upload for inspection results. Uses STS AssumeRole to write to the healthcheck output bucket. """ import json import os import logging import boto3 logger = logging.getLogger(__name__) # Output S3 bucket configuration (overridable via environment) OUTPUT_BUCKET = os.environ.get("OUTPUT_S3_BUCKET", "delicated-healthcheck") OUTPUT_REGION = os.environ.get("OUTPUT_S3_REGION", "us-west-2") TARGET_ROLE_ARN = os.environ.get("TARGET_ROLE_ARN", "") OUTPUT_AWS_PROFILE = os.environ.get("OUTPUT_AWS_PROFILE", "") def _get_s3_client(): """Get an S3 client for the output bucket. Credential resolution order: 1. TARGET_ROLE_ARN set → AssumeRole (production via IRSA) 2. OUTPUT_AWS_PROFILE set → use that named profile (local testing) 3. Otherwise → default boto3 credential chain """ if TARGET_ROLE_ARN: sts = boto3.client("sts") resp = sts.assume_role( RoleArn=TARGET_ROLE_ARN, RoleSessionName="healthcheck-upload", ) creds = resp["Credentials"] return boto3.client( "s3", region_name=OUTPUT_REGION, aws_access_key_id=creds["AccessKeyId"], aws_secret_access_key=creds["SecretAccessKey"], aws_session_token=creds["SessionToken"], ) if OUTPUT_AWS_PROFILE: session = boto3.Session(profile_name=OUTPUT_AWS_PROFILE) return session.client("s3", region_name=OUTPUT_REGION) return boto3.client("s3", region_name=OUTPUT_REGION) def upload_result_to_s3(result: dict, s3_key: str) -> str: """ Upload inspection result JSON to S3. Args: result: Inspection result dictionary. s3_key: S3 object key, e.g. healthcheck-report/{clusterId}_{reportId}_{name}.json Returns: S3 URI of the uploaded file. """ s3 = _get_s3_client() body = json.dumps(result, indent=2, ensure_ascii=False) s3.put_object( Bucket=OUTPUT_BUCKET, Key=s3_key, Body=body.encode("utf-8"), ContentType="application/json", ) s3_uri = f"s3://{OUTPUT_BUCKET}/{s3_key}" logger.info("Uploaded result to %s", s3_uri) return s3_uri