Skip to content

Commit

Permalink
Fixed the zombie_cluster global resources
Browse files Browse the repository at this point in the history
  • Loading branch information
athiruma committed Sep 17, 2024
1 parent a2243ce commit 5c559a8
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 101 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import typeguard
from moto.iam.exceptions import NoSuchEntity

from cloud_governance.common.logger.init_logger import logger

Expand Down Expand Up @@ -68,13 +69,17 @@ def __delete_user(self, resource_id: str):
try:
# Detach policy from user
user_policies = self.iam_client.list_user_policies(UserName=resource_id)
if user_policies['PolicyNames']:
self.iam_client.delete_user_policy(UserName=resource_id, PolicyName=f'{resource_id}-policy')
try:
if user_policies['PolicyNames']:
self.iam_client.delete_user_policy(UserName=resource_id, PolicyName=f'{resource_id}-policy')
except Exception:
logger.exception(f'Cannot delete_policies: {user_policies.get("PolicyNames")}')
list_access_key = self.iam_client.list_access_keys(UserName=resource_id)
# @Todo user_delete permission is very problematic operation, it might affect other users.
# delete user access key
for access_key in list_access_key['AccessKeyMetadata']:
self.iam_client.delete_access_key(UserName=resource_id, AccessKeyId=access_key['AccessKeyId'])
self.iam_client.delete_user(UserName=resource_id)
# for access_key in list_access_key['AccessKeyMetadata']:
# self.iam_client.delete_access_key(UserName=resource_id, AccessKeyId=access_key['AccessKeyId'])
# self.iam_client.delete_user(UserName=resource_id)
logger.info(f'delete_user: {resource_id}')
except Exception as err:
logger.exception(f'Cannot delete_user: {resource_id}, {err}')
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from cloud_governance.common.clouds.aws.utils.common_methods import get_tag_value_from_tags
from cloud_governance.common.elasticsearch.elasticsearch_operations import ElasticSearchOperations
from cloud_governance.main.environment_variables import environment_variables
from cloud_governance.policy.policy_operations.aws.zombie_cluster.zombie_cluster_common_methods import ZombieClusterCommonMethods
from cloud_governance.policy.policy_operations.aws.zombie_cluster.zombie_cluster_common_methods import \
ZombieClusterCommonMethods
from cloud_governance.common.logger.init_logger import logger
from cloud_governance.common.logger.logger_time_stamp import logger_time_stamp
from cloud_governance.policy.aws.zombie_cluster_resource import ZombieClusterResources
Expand Down Expand Up @@ -54,8 +55,8 @@ def __get_resource_list(region, delete: bool = False, resource: str = '', cluste
zombie_cluster_resources.zombie_cluster_subnet,
zombie_cluster_resources.zombie_cluster_vpc
]
iam_zombie_resource_services = [zombie_cluster_resources.zombie_cluster_role,
zombie_cluster_resources.zombie_cluster_user]
iam_zombie_resource_services = [zombie_cluster_resources.zombie_cluster_role]
# [zombie_cluster_resources.zombie_cluster_user]
s3_zombie_resource_services = [zombie_cluster_resources.zombie_cluster_s3_bucket]
scan_func_resource_list = []
delete_func_resource_list = []
Expand Down Expand Up @@ -116,6 +117,7 @@ def zombie_cluster_resource(delete: bool = False, region: str = 'us-east-2', res
zombie_cluster_common_methods = ZombieClusterCommonMethods(region=region)
cluster_delete_days = {}
zombie_cluster_resources_ids = {}
zombie_cluster_resources_data = {}
for func in func_resource_list:
resource_data, cluster_left_out_days = func()
if resource_data:
Expand All @@ -127,7 +129,9 @@ def zombie_cluster_resource(delete: bool = False, region: str = 'us-east-2', res
for resource_id, cluster_name in resource_data.items():
zombie_cluster_resources_ids.setdefault(cluster_name.strip(), []).append(resource_id)
cluster_delete_days[cluster_name] = get_tag_value_from_tags(tag_name='ClusterDeleteDays',
tags=cluster_left_out_days.get(cluster_name, []))
tags=cluster_left_out_days.get(cluster_name,
[]))
zombie_cluster_resources_data.setdefault(cluster_name, []).append(func.__name__)
resource_data_list = [func.__name__.replace("zombie_cluster_", "") + ':' + item for item in
resource_data_list]
logger.info(f'key: {func.__name__}, count: {len(resource_data)}, data: {resource_data_list}')
Expand All @@ -147,13 +151,25 @@ def zombie_cluster_resource(delete: bool = False, region: str = 'us-east-2', res
es_index = environment_variables_dict.get('es_index')
account = environment_variables_dict.get('account', '')
if zombie_cluster_result:
regional_zombie_cluster_ids = []
global_zombie_cluster_resources = ['zombie_cluster_role', 'zombie_cluster_s3_bucket']
for zombie_cluster_id, resources_data in zombie_cluster_resources_data.items():
if (len(resources_data) > 0 and resources_data[0] in global_zombie_cluster_resources) \
or (len(resources_data) > 1 and resources_data[1] in global_zombie_cluster_resources):
if region == 'us-east-1':
regional_zombie_cluster_ids.append(zombie_cluster_id)
else:
continue
else:
regional_zombie_cluster_ids.append(zombie_cluster_id)
for zombie_cluster in zombie_cluster_result:
zombie_cluster['region_name'] = region
zombie_cluster['account'] = account
zombie_cluster['ResourceIds'] = zombie_cluster_resources_ids[zombie_cluster['ResourceId']]
zombie_cluster['CleanUpDays'] = cluster_delete_days[zombie_cluster['ZombieClusterTag']]
es_operations.upload_to_elasticsearch(data=zombie_cluster.copy(), index=es_index)
logger.info(f'Uploaded the policy results to elasticsearch index: {es_index}')
if zombie_cluster['ZombieClusterTag'] in regional_zombie_cluster_ids:
zombie_cluster['region_name'] = region
zombie_cluster['account'] = account
zombie_cluster['ResourceIds'] = zombie_cluster_resources_ids[zombie_cluster['ResourceId']]
zombie_cluster['CleanUpDays'] = cluster_delete_days[zombie_cluster['ZombieClusterTag']]
es_operations.upload_to_elasticsearch(data=zombie_cluster.copy(), index=es_index)
logger.info(f'Uploaded the policy results to elasticsearch index: {es_index}')
else:
logger.error(f'No data to upload on @{account} at {datetime.utcnow()}')
else:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
import uuid
from datetime import datetime

import boto3

from cloud_governance.common.clouds.aws.utils.utils import Utils
from cloud_governance.policy.aws.zombie_cluster_resource import ZombieClusterResources


def test_iam_zombie_user_create_and_delete():
"""
This method checks weather the zombie users exists or not
:return:
"""
short_random_id = uuid.uuid1()
time_ms = str(datetime.utcnow().strftime('%f'))
USER_NAME = f'integration-ocp-{short_random_id}-{time_ms}'
iam_resource = boto3.client('iam')
tags = [
{'Key': f'kubernetes.io/cluster/{USER_NAME}', 'Value': 'Owned'},
{'Key': 'Owner', 'Value': 'integration'}
]
try:
iam_resource.create_user(UserName=USER_NAME, Tags=tags)
zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=False,
cluster_tag=f'kubernetes.io/cluster/{USER_NAME}',
resource_name='zombie_cluster_user', force_delete=True)
assert len(zombie_cluster_resources.zombie_cluster_user()) >= 1
zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=True,
cluster_tag=f'kubernetes.io/cluster/{USER_NAME}',
resource_name='zombie_cluster_user', force_delete=True)
zombie_cluster_resources.zombie_cluster_user()
iam_users = Utils().get_details_resource_list(func_name=iam_resource.list_users, input_tag='Users',
check_tag='Marker')
find = False
for user in iam_users:
if user['UserName'] == USER_NAME:
find = True
break
assert not find
except Exception as err:
iam_users = Utils().get_details_resource_list(func_name=iam_resource.list_users, input_tag='Users', check_tag='Marker')
for user in iam_users:
if user['UserName'] == USER_NAME:
iam_resource.delete_user(UserName=USER_NAME)
raise Exception('Failed to delete User')
# import uuid
# from datetime import datetime
#
# import boto3
#
# from cloud_governance.common.clouds.aws.utils.utils import Utils
# from cloud_governance.policy.aws.zombie_cluster_resource import ZombieClusterResources
#
#
# def test_iam_zombie_user_create_and_delete():
# """
# This method checks weather the zombie users exists or not
# :return:
# """
# short_random_id = uuid.uuid1()
# time_ms = str(datetime.utcnow().strftime('%f'))
# USER_NAME = f'integration-ocp-{short_random_id}-{time_ms}'
# iam_resource = boto3.client('iam')
# tags = [
# {'Key': f'kubernetes.io/cluster/{USER_NAME}', 'Value': 'Owned'},
# {'Key': 'Owner', 'Value': 'integration'}
# ]
# try:
# iam_resource.create_user(UserName=USER_NAME, Tags=tags)
# zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=False,
# cluster_tag=f'kubernetes.io/cluster/{USER_NAME}',
# resource_name='zombie_cluster_user', force_delete=True)
# assert len(zombie_cluster_resources.zombie_cluster_user()) >= 1
# zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=True,
# cluster_tag=f'kubernetes.io/cluster/{USER_NAME}',
# resource_name='zombie_cluster_user', force_delete=True)
# zombie_cluster_resources.zombie_cluster_user()
# iam_users = Utils().get_details_resource_list(func_name=iam_resource.list_users, input_tag='Users',
# check_tag='Marker')
# find = False
# for user in iam_users:
# if user['UserName'] == USER_NAME:
# find = True
# break
# assert not find
# except Exception as err:
# iam_users = Utils().get_details_resource_list(func_name=iam_resource.list_users, input_tag='Users', check_tag='Marker')
# for user in iam_users:
# if user['UserName'] == USER_NAME:
# iam_resource.delete_user(UserName=USER_NAME)
# raise Exception('Failed to delete User')
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from unittest import skip

# TEST DRY RUN: delete=False
from cloud_governance.policy.aws.zombie_cluster_resource import ZombieClusterResources


zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=False, region='us-east-2')
zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=False,
region='us-east-2')


def test_all_clusters():
Expand Down Expand Up @@ -111,7 +112,7 @@ def test_zombie_cluster_internet_gateway():
This method return all cluster internet_gateway
:return:
"""
assert len(zombie_cluster_resources.zombie_cluster_internet_gateway()[0]) >= 0
assert len(zombie_cluster_resources.zombie_cluster_internet_gateway()[0]) >= 0


def test_zombie_cluster_dhcp_option():
Expand Down Expand Up @@ -154,6 +155,7 @@ def test_zombie_cluster_role():
assert len(zombie_cluster_resources.zombie_cluster_role()[0]) >= 0


@skip(reason='Skipping the zombie cluster user')
def test_zombie_cluster_user():
"""
This method return all zombie cluster user, scan cluster in all regions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import json
from unittest import skip

from moto import mock_iam, mock_ec2
import boto3

from cloud_governance.common.clouds.aws.utils.utils import Utils
from cloud_governance.policy.aws.zombie_cluster_resource import ZombieClusterResources


EC2_POLICY = {
"Version": "2012-10-17",
"Statement": [
Expand Down Expand Up @@ -48,25 +48,26 @@ def test_delete_iam_cluster_role():
"""
iam_resource = boto3.client('iam')
assume_role_policy_document = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
tags = [
{'Key': 'kubernetes.io/cluster/unittest-test-cluster', 'Value': 'Owned'},
{'Key': 'Owner', 'Value': 'unitest'}
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
tags = [
{'Key': 'kubernetes.io/cluster/unittest-test-cluster', 'Value': 'Owned'},
{'Key': 'Owner', 'Value': 'unitest'}
]
iam_resource.create_role(AssumeRolePolicyDocument=json.dumps(assume_role_policy_document),
RoleName='unittest-ocp-test-worker-role', Tags=tags)
policy_output = iam_resource.create_policy(PolicyName='unittest-ocp-test-worker-policy', PolicyDocument=json.dumps(EC2_POLICY), Tags=tags)
policy_output = iam_resource.create_policy(PolicyName='unittest-ocp-test-worker-policy',
PolicyDocument=json.dumps(EC2_POLICY), Tags=tags)
iam_resource.attach_role_policy(RoleName='unittest-ocp-test-worker-role', PolicyArn=policy_output['Policy']['Arn'])

iam_resource.create_instance_profile(InstanceProfileName='unittest-ocp-test-worker-profile', Tags=tags)
Expand All @@ -76,8 +77,9 @@ def test_delete_iam_cluster_role():
zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=True,
cluster_tag='kubernetes.io/cluster/unittest-test-cluster',
resource_name='zombie_cluster_role', force_delete=True)
zombie_cluster_resources. zombie_cluster_role()
iam_roles = Utils().get_details_resource_list(func_name=iam_resource.list_roles, input_tag='Roles', check_tag='Marker')
zombie_cluster_resources.zombie_cluster_role()
iam_roles = Utils().get_details_resource_list(func_name=iam_resource.list_roles, input_tag='Roles',
check_tag='Marker')
find = False
for role in iam_roles:
if role['RoleName'] == 'unittest-ocp-test-worker-role':
Expand All @@ -96,25 +98,26 @@ def test_not_delete_iam_cluster_role():
"""
iam_resource = boto3.client('iam')
assume_role_policy_document = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
tags = [
{'Key': 'kubernetes.io/cluster/unittest-test-cluster', 'Value': 'Owned'},
{'Key': 'Owner', 'Value': 'unitest'}
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
tags = [
{'Key': 'kubernetes.io/cluster/unittest-test-cluster', 'Value': 'Owned'},
{'Key': 'Owner', 'Value': 'unitest'}
]
iam_resource.create_role(AssumeRolePolicyDocument=json.dumps(assume_role_policy_document),
RoleName='unittest-ocp-test-worker-role', Tags=tags)
policy_output = iam_resource.create_policy(PolicyName='unittest-ocp-test-worker-policy', PolicyDocument=json.dumps(EC2_POLICY), Tags=tags)
policy_output = iam_resource.create_policy(PolicyName='unittest-ocp-test-worker-policy',
PolicyDocument=json.dumps(EC2_POLICY), Tags=tags)
iam_resource.attach_role_policy(RoleName='unittest-ocp-test-worker-role', PolicyArn=policy_output['Policy']['Arn'])

iam_resource.create_instance_profile(InstanceProfileName='unittest-ocp-test-worker-profile', Tags=tags)
Expand All @@ -124,8 +127,9 @@ def test_not_delete_iam_cluster_role():
zombie_cluster_resources = ZombieClusterResources(cluster_prefix='kubernetes.io/cluster/', delete=True,
cluster_tag='kubernetes.io/cluster/unittest-test-cluster',
resource_name='zombie_cluster_role')
zombie_cluster_resources. zombie_cluster_role()
iam_roles = Utils().get_details_resource_list(func_name=iam_resource.list_roles, input_tag='Roles', check_tag='Marker')
zombie_cluster_resources.zombie_cluster_role()
iam_roles = Utils().get_details_resource_list(func_name=iam_resource.list_roles, input_tag='Roles',
check_tag='Marker')
find = False
for role in iam_roles:
if role['RoleName'] == 'unittest-ocp-test-worker-role':
Expand All @@ -136,6 +140,7 @@ def test_not_delete_iam_cluster_role():

@mock_ec2
@mock_iam
@skip(reason='Skipping the zombie cluster user')
def test_delete_iam_cluster_user():
"""
This method tests the user has successfully deleted or not
Expand All @@ -162,6 +167,7 @@ def test_delete_iam_cluster_user():

@mock_ec2
@mock_iam
@skip(reason='Skipping the zombie cluster user')
def test_not_delete_iam_cluster_user():
"""
This method tests the user has not deleted
Expand Down

0 comments on commit 5c559a8

Please sign in to comment.