cloud-governance 1.1.389__py3-none-any.whl → 1.1.390__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -318,3 +318,47 @@ class IAMOperations:
318
318
  logger.info(f"Access key '{access_key_id}' is already inactive for user '{username}'")
319
319
 
320
320
  logger.info(f"Access key deactivation processed for user '{username}'.")
321
+
322
+ def get_instance_profiles_for_role(self, role_name: str):
323
+ """
324
+ This method returns instance profiles associated with a given IAM role.
325
+ :param role_name: The name of the IAM role.
326
+ :return: A list of instance profiles.
327
+ """
328
+ instance_profiles = []
329
+ try:
330
+ # list_instance_profiles_for_role is paginated, use Utils to handle pagination
331
+ instance_profiles = self.utils.get_details_resource_list(
332
+ func_name=self.iam_client.list_instance_profiles_for_role,
333
+ input_tag='InstanceProfiles',
334
+ check_tag='Marker',
335
+ RoleName=role_name
336
+ )
337
+ except Exception as err:
338
+ logger.error(f"Failed to list instance profiles for role '{role_name}': {err}")
339
+ return instance_profiles
340
+
341
+ def remove_role_from_instance_profiles(self, role_name: str):
342
+ """
343
+ This method removes the specified IAM role from all associated instance profiles.
344
+ :param role_name: The name of the role to remove.
345
+ :return: True if removal from all profiles is successful, False otherwise.
346
+ """
347
+ instance_profiles = self.get_instance_profiles_for_role(role_name=role_name)
348
+ if not instance_profiles:
349
+ return True
350
+
351
+ success = True
352
+ for ip in instance_profiles:
353
+ instance_profile_name = ip.get('InstanceProfileName')
354
+ try:
355
+ self.iam_client.remove_role_from_instance_profile(
356
+ InstanceProfileName=instance_profile_name,
357
+ RoleName=role_name
358
+ )
359
+ logger.info(f"Successfully removed role '{role_name}' from instance profile '{instance_profile_name}'")
360
+ except Exception as err:
361
+ logger.error(
362
+ f"Failed to remove role '{role_name}' from instance profile '{instance_profile_name}': {err}")
363
+ success = False
364
+ return success
@@ -15,7 +15,7 @@ class EmptyRoles(AWSPolicyOperations):
15
15
 
16
16
  def run_policy_operations(self):
17
17
  """
18
- This method returns all Empty buckets
18
+ This method returns all Empty roles.
19
19
  :return:
20
20
  :rtype:
21
21
  """
@@ -33,7 +33,33 @@ class EmptyRoles(AWSPolicyOperations):
33
33
  try:
34
34
  if not cluster_tag and len(inline_policies) == 0 and len(attached_policies) == 0 and \
35
35
  self.get_skip_policy_value(tags=tags) not in ('NOTDELETE', 'SKIP'):
36
+
36
37
  cleanup_days = self.get_clean_up_days_count(tags=tags)
38
+ # Step 1: Remove role from all instance profiles if attached (for empty roles)
39
+ instance_profiles = self._iam_operations.get_instance_profiles_for_role(role_name=role_name)
40
+ detachment_success = True
41
+ if instance_profiles:
42
+ logger.info(
43
+ f"Role '{role_name}' is empty (no policies) but attached to instance profile(s): "
44
+ f"{[ip['InstanceProfileName'] for ip in instance_profiles]}. Detaching now...")
45
+
46
+ # Call the new method to handle detachment if dry_run = 'no'
47
+ if self._dry_run == 'no':
48
+ detachment_success = self._iam_operations.remove_role_from_instance_profiles(
49
+ role_name=role_name)
50
+ logger.warning(f"LIVE RUN: Detachment attempted. Success: {detachment_success}")
51
+ else:
52
+ logger.info(f"DRY RUN: Skipping actual detachment of role '{role_name}'.")
53
+
54
+ if not detachment_success:
55
+ # Skip deletion if detachment failed
56
+ logger.info(
57
+ f"Failed to detach role '{role_name}' from all instance profiles. Skipping deletion.")
58
+ self.update_resource_day_count_tag(resource_id=role_name, cleanup_days=cleanup_days,
59
+ tags=tags)
60
+ continue
61
+
62
+ # Step 2: Proceed with deletion
37
63
  cleanup_result = self.verify_and_delete_resource(resource_id=role_name, tags=tags,
38
64
  clean_up_days=cleanup_days)
39
65
  resource_data = self._get_es_schema(resource_id=role_name,
@@ -50,8 +76,10 @@ class EmptyRoles(AWSPolicyOperations):
50
76
  resource_state="Empty",
51
77
  unit_price=0)
52
78
  empty_roles.append(resource_data)
79
+
53
80
  if not cleanup_result:
54
81
  self.update_resource_day_count_tag(resource_id=role_name, cleanup_days=cleanup_days, tags=tags)
82
+
55
83
  except Exception as e:
56
84
  logger.error(f'Exception raised while processing the empty roles operation on {role_name}, {e}')
57
85
  return empty_roles
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloud-governance
3
- Version: 1.1.389
3
+ Version: 1.1.390
4
4
  Summary: Cloud Governance Tool
5
5
  Home-page: https://github.com/redhat-performance/cloud-governance
6
6
  Author: Red Hat
@@ -51,7 +51,7 @@ cloud_governance/common/clouds/aws/dynamodb/dynamodb_operations.py,sha256=eeV3Yg
51
51
  cloud_governance/common/clouds/aws/ec2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  cloud_governance/common/clouds/aws/ec2/ec2_operations.py,sha256=0ibMvf7nqyK9MCRhxrg11xnOPELqsZIQsZUgd6_neKc,24680
53
53
  cloud_governance/common/clouds/aws/iam/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- cloud_governance/common/clouds/aws/iam/iam_operations.py,sha256=cQWh1iJdlQCGVcZcQF6aDt8fQrKnv6n-361xALNQ7QQ,11732
54
+ cloud_governance/common/clouds/aws/iam/iam_operations.py,sha256=rrtMIw50VugdRJLOQhXEj2BB9FcscIt-mQfCF2qWb9U,13719
55
55
  cloud_governance/common/clouds/aws/price/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
56
  cloud_governance/common/clouds/aws/price/price.py,sha256=Ju76WniNTVujQPi6QFRgLt6Jd8gsxL2FOnN7c1et5F0,6403
57
57
  cloud_governance/common/clouds/aws/price/resources_pricing.py,sha256=k-hucUvxpZfF126wLQQwJt3BzNQiOoSU1x6gjIQ_4cM,6253
@@ -159,7 +159,7 @@ cloud_governance/policy/aws/cost_explorer_payer_billings.py,sha256=EuTry807RRw0S
159
159
  cloud_governance/policy/aws/cost_over_usage.py,sha256=-XEZGNlu7KIGSpEDJgQVcc2fNrPALqrKqgGGV3vbdVM,5998
160
160
  cloud_governance/policy/aws/ebs_in_use.py,sha256=7vGV2qobV14rzC7tJnJiafC3oAhnY_TTvd53oEtaN4Q,616
161
161
  cloud_governance/policy/aws/ec2_stop.py,sha256=FXQNkHmiMCEw6Pz6CalIIVYFRsV24RT5TewqFazyP8M,9641
162
- cloud_governance/policy/aws/empty_roles.py,sha256=EhsepFRbjU82PjJQ1hADqBM_RO1Ukr-Q4DZAz3bM4ho,3155
162
+ cloud_governance/policy/aws/empty_roles.py,sha256=gEBaribxBnM_seP8rcifaVdf-Gz-JT2sc1aNKl8AcxA,4804
163
163
  cloud_governance/policy/aws/ip_unattached.py,sha256=OnHlTIKSgyxwdAgU9jBApdvDQpzHgECjSodN6KoXWqU,3176
164
164
  cloud_governance/policy/aws/monthly_report.py,sha256=cSeOfdU5u2BMUR1RmxTrrxpMSlOCG0oqKUeSqwdU_jY,6830
165
165
  cloud_governance/policy/aws/optimize_resources_report.py,sha256=zG7w8KHF7Z25jxYGgDadyXp0jcxSREsRCOmQP8lZMNc,6003
@@ -265,8 +265,8 @@ cloud_governance/policy/policy_runners/elasticsearch/__init__.py,sha256=47DEQpj8
265
265
  cloud_governance/policy/policy_runners/elasticsearch/upload_elastic_search.py,sha256=pOwUJWXjJbyTy8iv3Ap8xJGnqQe-5lZgoR8-vGfAVos,1881
266
266
  cloud_governance/policy/policy_runners/ibm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
267
267
  cloud_governance/policy/policy_runners/ibm/policy_runner.py,sha256=V0E_f7F3hXit0aSq4BlfX1Jd4vjR2NEvOWsJ5upvZ4o,1302
268
- cloud_governance-1.1.389.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
269
- cloud_governance-1.1.389.dist-info/METADATA,sha256=VAMZ4oVE8jWRMIijCUQ_Z-ELk-0DQ0BVivKPpOypVRo,11384
270
- cloud_governance-1.1.389.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
271
- cloud_governance-1.1.389.dist-info/top_level.txt,sha256=jfB1fgj7jvx3YZkZA4G6hFeS1RHO7J7XtnbjuMNMRww,17
272
- cloud_governance-1.1.389.dist-info/RECORD,,
268
+ cloud_governance-1.1.390.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
269
+ cloud_governance-1.1.390.dist-info/METADATA,sha256=GLZTMm4vq-oCFA2AzpHw8V2EK8uIthdudCidFvCRmpY,11384
270
+ cloud_governance-1.1.390.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
271
+ cloud_governance-1.1.390.dist-info/top_level.txt,sha256=jfB1fgj7jvx3YZkZA4G6hFeS1RHO7J7XtnbjuMNMRww,17
272
+ cloud_governance-1.1.390.dist-info/RECORD,,