Skip to content

Commit f7bde0f

Browse files
sureshcsdpSuresh Mandalapu
andauthored
AWS: hardening rules - part 2 (#159)
* aws.ec2.elastic_ip.unattached * aws.elb.idle * aws.ec2.eni.detached * aws.ec2.nat_gateway.idle * aws.rds.instance.idle --------- Co-authored-by: Suresh Mandalapu <suresh@Sureshs-MacBook-Air.local>
1 parent 2dccd62 commit f7bde0f

24 files changed

Lines changed: 7541 additions & 2813 deletions

cleancloud.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ rules:
6161

6262
aws.rds.instance.idle:
6363
enabled: true
64-
min_cost: 100 # suppress RDS findings below $100/month estimated cost
6564
params:
66-
idle_days: 21 # require 21 days idle before flagging (default: 14)
65+
idle_days_threshold: 21 # require 21 days idle before flagging (default: 14)
6766

6867
gcp.sql.instance.idle:
6968
enabled: true

cleancloud/providers/aws/rules/ai/ec2_gpu_idle.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ def _list_gpu_metrics(cloudwatch, instance_id: str) -> list:
397397
Dimensions=[{"Name": "InstanceId", "Value": instance_id}],
398398
)
399399
return resp.get("Metrics", [])
400-
except ClientError:
400+
except Exception:
401401
return []
402402

403403

@@ -434,7 +434,7 @@ def _get_max_gpu_utilisation(
434434
gpu_max = max(dp["Maximum"] for dp in datapoints)
435435
if max_util is None or gpu_max > max_util:
436436
max_util = gpu_max
437-
except ClientError:
437+
except Exception:
438438
continue
439439

440440
return max_util
@@ -467,5 +467,5 @@ def _get_avg_cpu_utilisation(
467467
if not datapoints:
468468
return None
469469
return max(dp["Maximum"] for dp in datapoints)
470-
except ClientError:
470+
except Exception:
471471
return None

cleancloud/providers/aws/rules/ai/sagemaker_endpoint_idle.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ def _check_invocations(
434434
queried_with_variants=False,
435435
fetch_failed=False,
436436
)
437-
except ClientError:
437+
except Exception:
438438
return InvocationCheckResult(
439439
has_traffic=True,
440440
active_variants=[],
@@ -471,7 +471,7 @@ def _check_invocations(
471471
else:
472472
idle_variants.append(variant_name)
473473

474-
except ClientError:
474+
except Exception:
475475
# CloudWatch API failure — treat this variant as active and surface the failure.
476476
return InvocationCheckResult(
477477
has_traffic=True,
@@ -561,7 +561,7 @@ def _describe_endpoint(
561561
slcfg = cv.get("ServerlessConfig")
562562
if slcfg:
563563
serverless_cfg_by_variant[cv["VariantName"]] = slcfg
564-
except ClientError:
564+
except Exception:
565565
pass # config inaccessible — costs/GPU will use defaults
566566

567567
accumulated_cost = 0.0
@@ -631,7 +631,7 @@ def _describe_endpoint(
631631
total_provisioned_concurrency,
632632
)
633633

634-
except ClientError:
634+
except Exception:
635635
# Unknown state — return zero instances so the endpoint is skipped rather
636636
# than flagged with assumed cost and instance count.
637637
return None, False, 0, 0, None, [], 0

cleancloud/providers/aws/rules/ami_old.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ def _get_last_launched_time(ec2, ami_id: str) -> Tuple[Optional[datetime], bool]
507507
if not isinstance(value, str) or not value:
508508
return None, False
509509
return datetime.fromisoformat(value.replace("Z", "+00:00")), False
510-
except ClientError:
510+
except Exception:
511511
return None, True
512512

513513

@@ -527,7 +527,7 @@ def _check_active_instances(ec2, ami_id: str) -> Tuple[bool, bool]:
527527
)
528528
found = any(r.get("Instances") for r in resp.get("Reservations", []))
529529
return found, False
530-
except ClientError:
530+
except Exception:
531531
return False, True
532532

533533

@@ -572,11 +572,11 @@ def _build_lt_index(ec2) -> Tuple[Dict[str, List[str]], bool]:
572572
v_lt_id = v.get("LaunchTemplateId")
573573
if image_id and v_lt_id:
574574
index.setdefault(image_id, set()).add(v_lt_id)
575-
except ClientError:
575+
except Exception:
576576
continue # best-effort per LT
577577

578578
return {k: sorted(v) for k, v in index.items()}, lt_truncated
579-
except ClientError:
579+
except Exception:
580580
return {}, True
581581

582582

@@ -610,5 +610,5 @@ def _build_lc_index(autoscaling) -> Tuple[Dict[str, List[str]], bool]:
610610
break
611611
kwargs["NextToken"] = nxt
612612
return {k: sorted(v) for k, v in index.items()}, lc_truncated
613-
except ClientError:
613+
except Exception:
614614
return {}, True

cleancloud/providers/aws/rules/ebs_snapshot_old.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
from typing import List, Optional, Set, Tuple
3838

3939
import boto3
40-
from botocore.exceptions import BotoCoreError, ClientError
4140

4241
from cleancloud.core.confidence import ConfidenceLevel
4342
from cleancloud.core.evidence import Evidence
@@ -68,7 +67,7 @@ def _build_ami_snapshot_index(ec2) -> Tuple[Set[str], bool]:
6867
snap_id = bdm.get("Ebs", {}).get("SnapshotId")
6968
if snap_id:
7069
referenced.add(snap_id)
71-
except (ClientError, BotoCoreError):
70+
except Exception:
7271
return referenced, True
7372
return referenced, False
7473

@@ -91,7 +90,7 @@ def _check_external_sharing(ec2, snap_id: str) -> Tuple[bool, bool]:
9190
if perm.get("UserId"): # explicit cross-account
9291
return True, False
9392
return False, False
94-
except (ClientError, BotoCoreError):
93+
except Exception:
9594
return False, True
9695

9796

cleancloud/providers/aws/rules/ec2_sg_unused.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def find_unused_security_groups(
262262
)
263263
if name:
264264
vpc_names[vpc["VpcId"]] = name
265-
except (ClientError, BotoCoreError):
265+
except Exception:
266266
pass # VPC names are display-only; don't fail the rule
267267

268268
# --- Step 7: Apply exclusion rules and emit findings ---

cleancloud/providers/aws/rules/ec2_stopped.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def _get_volume_sizes(ec2, volume_ids: List[str]) -> Dict[str, int]:
331331
size = vol.get("Size")
332332
if vid and size is not None:
333333
sizes[vid] = size
334-
except (ClientError, BotoCoreError):
334+
except Exception:
335335
pass
336336
return sizes
337337

0 commit comments

Comments
 (0)