diff --git a/cloud_governance/main/main_oerations/main_operations.py b/cloud_governance/main/main_oerations/main_operations.py index 53a92c25..ffe7a619 100644 --- a/cloud_governance/main/main_oerations/main_operations.py +++ b/cloud_governance/main/main_oerations/main_operations.py @@ -38,7 +38,7 @@ def run(self): policy_runner = self.get_policy_runner() for policy_type, policies in policies_list.items(): # @Todo support for all the aws policies, currently supports ec2_run as urgent requirement - if self._policy in policies and self._policy in ["instance_run", "unattached_volume"]: + if self._policy in policies and self._policy in ["instance_run", "unattached_volume", "cluster_run"]: policy_runner.run(source=policy_type) return True return False diff --git a/cloud_governance/policy/aws/monitor/__init__.py b/cloud_governance/policy/aws/monitor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cloud_governance/policy/aws/monitor/cluster_run.py b/cloud_governance/policy/aws/monitor/cluster_run.py new file mode 100644 index 00000000..48e334fc --- /dev/null +++ b/cloud_governance/policy/aws/monitor/cluster_run.py @@ -0,0 +1,62 @@ +import datetime +import re + +from cloud_governance.cloud_resource_orchestration.utils.common_operations import string_equal_ignore_case +from cloud_governance.policy.helpers.aws.aws_policy_operations import AWSPolicyOperations + + +class ClusterRun(AWSPolicyOperations): + """ + This class performs the operations on running cluster resources + """ + + def __init__(self): + super().__init__() + + def run_policy_operations(self): + """ + This method returns the running vms in the AAzure cloud and stops based on the action + :return: + :rtype: + """ + instances = self._get_all_instances() + cluster_data = {} + for instance in instances: + tags = instance.get('Tags', []) + cluster_tag = self._get_cluster_tag(tags=tags).strip() + instance_state = instance.get('State', {}).get('Name') + if cluster_tag and not string_equal_ignore_case(instance_state, 'terminated'): + launch_time = instance.get('LaunchTime') + running_instances = stopped_instances = 0 + running_days = self.calculate_days(instance.get('LaunchTime')) + if string_equal_ignore_case(instance_state, 'stopped'): + stopped_instances = 1 + state_transition_reason = instance.get('StateTransitionReason') + if state_transition_reason: + extract_data = re.search(r'\((\d{4}-\d{2}-\d{2})', state_transition_reason) + if extract_data: + running_days = self.calculate_days(extract_data.group(1).split()[0], start_date=launch_time) + instance_state += f"@{extract_data.group(1)}" + else: + running_instances = 1 + instance_data = f"{instance.get('InstanceId')}, {self.get_tag_name_from_tags(tags=tags, tag_name='Name')}, {instance.get('InstanceType')}, {instance_state}, {running_days}, {launch_time}" + if cluster_tag in cluster_data: + cluster_data[cluster_tag]['Instances'].append(instance_data) + cluster_data[cluster_tag]['InstanceCount'] = len(cluster_data[cluster_tag]['Instances']) + cluster_data[cluster_tag]['Stopped'] = int(cluster_data[cluster_tag]['Stopped']) + stopped_instances + cluster_data[cluster_tag]['Running'] = int(cluster_data[cluster_tag]['Running']) + running_instances + else: + cluster_data[cluster_tag] = { + 'ResourceId': cluster_tag, + 'ClusterTag': cluster_tag, + 'User': self.get_tag_name_from_tags(tags=tags, tag_name='User'), + 'RunningDays': running_days, + 'RegionName': self._region, + 'PublicCloud': self._cloud_name, + 'Instances': [instance_data], + 'InstanceCount': 1, + 'Stopped': stopped_instances, + 'Running': running_instances, + 'index-id': f'{datetime.datetime.utcnow().date()}-{self._cloud_name.lower()}-{self.account.lower()}-{self._region.lower()}-{cluster_tag}' + } + return list(cluster_data.values()) diff --git a/cloud_governance/policy/helpers/abstract_policy_operations.py b/cloud_governance/policy/helpers/abstract_policy_operations.py index a374f028..a79e7fb2 100644 --- a/cloud_governance/policy/helpers/abstract_policy_operations.py +++ b/cloud_governance/policy/helpers/abstract_policy_operations.py @@ -23,9 +23,11 @@ def __init__(self): self._resource_id = self._environment_variables_dict.get('RESOURCE_ID') self._es_upload = ElasticUpload() - def calculate_days(self, create_date: Union[datetime, str]): + def calculate_days(self, create_date: Union[datetime, str], start_date: Union[datetime, str] = datetime.utcnow()): """ This method returns the days + :param start_date: + :type start_date: :param create_date: :type create_date: :return: @@ -33,8 +35,10 @@ def calculate_days(self, create_date: Union[datetime, str]): """ if isinstance(create_date, str): create_date = datetime.strptime(create_date, "%Y-%M-%d") - today = datetime.utcnow().date() - days = today - create_date.date() + if isinstance(start_date, str): + start_date = datetime.strptime(start_date, "%Y-%m-%d") + start_date = start_date.date() + days = start_date - create_date.date() return days.days def get_clean_up_days_count(self, tags: Union[list, dict]): diff --git a/cloud_governance/policy/helpers/aws/aws_policy_operations.py b/cloud_governance/policy/helpers/aws/aws_policy_operations.py index 8a217d55..0b121027 100644 --- a/cloud_governance/policy/helpers/aws/aws_policy_operations.py +++ b/cloud_governance/policy/helpers/aws/aws_policy_operations.py @@ -150,3 +150,30 @@ def _get_all_volumes(self, **kwargs) -> list: """ volumes = self._ec2_operations.get_volumes(**kwargs) return volumes + + def _get_active_cluster_ids(self): + """ + This method returns the active cluster id's + :return: + :rtype: + """ + active_instances = self._ec2_operations.get_ec2_instance_list() + cluster_ids = [] + for instance in active_instances: + for tag in instance.get('Tags', []): + if tag.get('Key', '').startswith('kubernetes.io/cluster'): + cluster_ids.append(tag.get('Key')) + break + return cluster_ids + + def _get_cluster_tag(self, tags: list): + """ + This method returns the cluster_tag + :return: + :rtype: + """ + if tags: + for tag in tags: + if tag.get('Key').startswith('kubernetes.io/cluster'): + return tag.get('Key') + return ''