-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Azure: Added the ip_unattacheed policy #728
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
from azure.mgmt.network import NetworkManagementClient | ||
|
||
from cloud_governance.common.clouds.azure.compute.common_operations import CommonOperations | ||
from cloud_governance.common.utils.utils import Utils | ||
|
||
|
||
class NetworkOperations(CommonOperations): | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self.__network_client = NetworkManagementClient(self._default_creds, subscription_id=self._subscription_id) | ||
|
||
def __get_all_public_ip_address(self): | ||
""" | ||
This method returns all the Public address | ||
:return: | ||
:rtype: | ||
""" | ||
ips = self.__network_client.public_ip_addresses.list_all() | ||
return self._item_paged_iterator(item_paged_object=ips, as_dict=True) | ||
|
||
def get_public_ipv4_addresses(self): | ||
""" | ||
This method returns the Public IPV4 | ||
:return: | ||
:rtype: | ||
""" | ||
public_addresses = [] | ||
for ipaddress in self.__get_all_public_ip_address(): | ||
if Utils.equal_ignore_case(ipaddress.get('public_ip_address_version'), 'IPv4'): | ||
if Utils.equal_ignore_case(ipaddress.get('public_ip_allocation_method'), 'Static'): | ||
public_addresses.append(ipaddress) | ||
return public_addresses | ||
|
||
def __get_network_interfaces(self): | ||
""" | ||
This method returns the network interfaces | ||
:return: | ||
:rtype: | ||
""" | ||
network_interfaces = self.__network_client.network_interfaces.list_all() | ||
network_interfaces = self._item_paged_iterator(item_paged_object=network_interfaces, as_dict=True) | ||
return network_interfaces | ||
|
||
def get_public_ipv4_network_interfaces(self): | ||
""" | ||
This method returns the network interfaces have the public ip address attached | ||
:return: | ||
:rtype: | ||
""" | ||
public_ipv4_network_interfaces = {} | ||
network_interfaces = self.__get_network_interfaces() | ||
for network_interface in network_interfaces: | ||
for ip_configuration in network_interface.get('ip_configurations', []): | ||
if ip_configuration.get('public_ip_address', {}): | ||
public_ipv4_address_id = ip_configuration.get('public_ip_address', {}).get('id') | ||
public_ipv4_network_interfaces.setdefault(public_ipv4_address_id, []).append(network_interface) | ||
return public_ipv4_network_interfaces | ||
|
||
# delete operations | ||
def release_public_ip(self, resource_id: str): | ||
""" | ||
This method releases the public ip | ||
:return: | ||
:rtype: | ||
""" | ||
id_key_pairs = self.get_id_dict_data(resource_id) | ||
resource_group_name = id_key_pairs.get('resourcegroups') | ||
public_ip_address_name = id_key_pairs.get('publicipaddresses') | ||
status = self.__network_client.public_ip_addresses.begin_delete(resource_group_name=resource_group_name, | ||
public_ip_address_name=public_ip_address_name) | ||
return status.done() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,55 @@ | ||
from cloud_governance.policy.helpers.aws.aws_policy_operations import AWSPolicyOperations | ||
|
||
from cloud_governance.policy.policy_operations.aws.zombie_non_cluster.run_zombie_non_cluster_policies import NonClusterZombiePolicy | ||
|
||
|
||
class IpUnattached(NonClusterZombiePolicy): | ||
class IpUnattached(AWSPolicyOperations): | ||
""" | ||
Fetched the Unused elastic_ips( based on network interface Id) and delete it after 7 days of unused, | ||
alert user after 4 days of unused elastic_ip. | ||
""" | ||
|
||
RESOURCE_ACTION = "Delete" | ||
|
||
def __init__(self): | ||
super().__init__() | ||
|
||
def run(self): | ||
def run_policy_operations(self): | ||
""" | ||
This method returns zombie elastic_ip's and delete if dry_run no | ||
@return: | ||
This method returns the list of unattached IPV4 addresses | ||
:return: | ||
:rtype: | ||
""" | ||
addresses = self._ec2_operations.get_elastic_ips() | ||
zombie_addresses = [] | ||
active_cluster_ids = self._get_active_cluster_ids() | ||
unattached_addresses = [] | ||
for address in addresses: | ||
ip_no_used = False | ||
tags = address.get('Tags', []) | ||
if not self._check_cluster_tag(tags=tags) or self._get_policy_value(tags=tags) not in ('NOTDELETE', 'SKIP'): | ||
cleanup_result = False | ||
ip_not_used = False | ||
resource_id = address.get('AllocationId') | ||
cluster_tag = self._get_cluster_tag(tags=address.get('Tags')) | ||
if cluster_tag not in active_cluster_ids: | ||
if not address.get('NetworkInterfaceId'): | ||
ip_no_used = True | ||
unused_days = self._get_resource_last_used_days(tags=tags) | ||
eip_cost = self.resource_pricing.get_const_prices(resource_type='eip', hours=(self.DAILY_HOURS * unused_days)) | ||
delta_cost = 0 | ||
if unused_days == self.DAYS_TO_NOTIFY_ADMINS: | ||
delta_cost = self.resource_pricing.get_const_prices(resource_type='eip', hours=(self.DAILY_HOURS * (unused_days - self.DAYS_TO_TRIGGER_RESOURCE_MAIL))) | ||
else: | ||
if unused_days >= self.DAYS_TO_DELETE_RESOURCE: | ||
delta_cost = self.resource_pricing.get_const_prices(resource_type='eip', hours=(self.DAILY_HOURS * (unused_days - self.DAYS_TO_NOTIFY_ADMINS))) | ||
zombie_eip = self._check_resource_and_delete(resource_name='ElasticIp', | ||
resource_id='AllocationId', | ||
resource_type='AllocateAddress', | ||
resource=address, | ||
empty_days=unused_days, | ||
days_to_delete_resource=self.DAYS_TO_DELETE_RESOURCE, tags=tags, | ||
extra_purse=eip_cost, delta_cost=delta_cost) | ||
if zombie_eip: | ||
zombie_addresses.append({'ResourceId': address.get('AllocationId'), | ||
'Name': self._get_tag_name_from_tags(tags=tags), | ||
'User': self._get_tag_name_from_tags(tags=tags, tag_name='User'), | ||
'PublicIp': address.get('PublicIp'), | ||
'Skip': self._get_policy_value(tags=tags), | ||
'Days': unused_days}) | ||
cleanup_days = self.get_clean_up_days_count(tags=tags) | ||
ip_not_used = True | ||
cleanup_result = self.verify_and_delete_resource(resource_id=resource_id, tags=tags, | ||
clean_up_days=cleanup_days) | ||
resource_data = self._get_es_schema(resource_id=resource_id, | ||
user=self.get_tag_name_from_tags(tags=tags, tag_name='User'), | ||
skip_policy=self.get_skip_policy_value(tags=tags), | ||
cleanup_days=cleanup_days, dry_run=self._dry_run, | ||
name=self.get_tag_name_from_tags(tags=tags, tag_name='Name'), | ||
region=self._region, | ||
cleanup_result=str(cleanup_result), | ||
resource_action=self.RESOURCE_ACTION, | ||
cloud_name=self._cloud_name, | ||
resource_type='PublicIPv4', | ||
resource_state='disassociated' if not cleanup_result else "Deleted" | ||
) | ||
unattached_addresses.append(resource_data) | ||
else: | ||
unused_days = 0 | ||
self._update_resource_tags(resource_id=address.get('AllocationId'), tags=tags, left_out_days=unused_days, resource_left_out=ip_no_used) | ||
return zombie_addresses | ||
cleanup_days = 0 | ||
if not cleanup_result: | ||
if self.get_tag_name_from_tags(tags, tag_name='DaysCount') or ip_not_used: | ||
self.update_resource_day_count_tag(resource_id=resource_id, cleanup_days=cleanup_days, tags=tags) | ||
|
||
return unattached_addresses |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
|
||
from cloud_governance.policy.helpers.azure.azure_policy_operations import AzurePolicyOperations | ||
|
||
|
||
class IpUnattached(AzurePolicyOperations): | ||
|
||
RESOURCE_ACTION = "Delete" | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self.__network_interfaces = self.network_operations.get_public_ipv4_network_interfaces() | ||
|
||
def __check_ipv4_not_associated(self, ipv4_address_dict: dict): | ||
""" | ||
This method returns bool | ||
:param ipv4_address_dict: | ||
:type ipv4_address_dict: | ||
:return: | ||
:rtype: | ||
""" | ||
found = False | ||
ip_address_id = ipv4_address_dict.get('id') | ||
if not ipv4_address_dict.get('ip_configuration'): | ||
found = True | ||
else: | ||
network_interface_id = ipv4_address_dict.get('ip_configuration', {}).get('id') | ||
if ip_address_id in self.__network_interfaces: | ||
for network_interface in self.__network_interfaces.get(ip_address_id): | ||
if network_interface.get('id') in network_interface_id: | ||
if not network_interface.get('virtual_machine'): | ||
found = True | ||
return found | ||
|
||
def run_policy_operations(self, volume=None): | ||
""" | ||
This method returns the list of unattached IPV4's | ||
:return: | ||
:rtype: | ||
""" | ||
unattached_ips = [] | ||
active_cluster_ids = self._get_active_cluster_ids() | ||
public_ipv4_address = self.network_operations.get_public_ipv4_addresses() | ||
for ip_address in public_ipv4_address: | ||
tags = ip_address.get('tags') | ||
cleanup_result = False | ||
is_disassociated_ipv4 = False | ||
cluster_tag = self._get_cluster_tag(tags=tags) | ||
if cluster_tag not in active_cluster_ids: | ||
Comment on lines
+47
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did we add the same for AWS policy ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
is_disassociated_ipv4 = self.__check_ipv4_not_associated(ip_address) | ||
if is_disassociated_ipv4: | ||
cleanup_days = self.get_clean_up_days_count(tags=tags) | ||
cleanup_result = self.verify_and_delete_resource(resource_id=ip_address.get('id'), tags=tags, | ||
clean_up_days=cleanup_days) | ||
resource_data = self._get_es_schema(resource_id=ip_address.get('name'), | ||
user=self.get_tag_name_from_tags(tags=tags, tag_name='User'), | ||
skip_policy=self.get_skip_policy_value(tags=tags), | ||
cleanup_days=cleanup_days, dry_run=self._dry_run, | ||
name=ip_address.get('name'), region=ip_address.get('location'), | ||
cleanup_result=str(cleanup_result), | ||
resource_action=self.RESOURCE_ACTION, | ||
cloud_name=self._cloud_name, | ||
resource_type="PublicIPv4 Static", | ||
resource_state="disassociated" if not cleanup_result else "Deleted" | ||
) | ||
unattached_ips.append(resource_data) | ||
else: | ||
cleanup_days = 0 | ||
if not cleanup_result: | ||
if self.get_tag_name_from_tags(tags, tag_name='DaysCount') or is_disassociated_ipv4: | ||
self.update_resource_day_count_tag(resource_id=ip_address.get("id"), | ||
cleanup_days=cleanup_days, tags=tags) | ||
return unattached_ips |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check cluster tag not in active clusters