Skip to content
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

Alert in slack channel #811

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 66 additions & 19 deletions cloudsensei/lambda_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,28 @@ class EC2Operations:
"""

SLACK_ITEM_SIZE = 50
KEYS_LIST = ['User', 'TicketId', 'Region', 'Name', 'InstanceType', 'InstanceId', 'LaunchDate', 'State',
'RunningDays']

def __init__(self):
self.__ec2_client = boto3.client('ec2', region_name='us-east-1')
self.__iam_client = boto3.client('iam')
self.__resource_days = int(os.environ.get('RESOURCE_DAYS', 7))
self.__users_mapping_list = self.get_user_mapping()

def get_user_mapping(self):
"""
This method returns the user mappings
:return:
"""
users_mapping_list = {}
mapping_list = os.environ.get('USERS_MAPPING_LIST', '') # "user1: kerberosid, user2:kerberosid"
if mapping_list:
mapping_list = mapping_list.split(',')
for user in mapping_list:
key, value = user.split(':')
users_mapping_list[key] = value
return users_mapping_list

def set_ec2_client(self, region_name: str):
"""
Expand Down Expand Up @@ -77,15 +94,18 @@ def get_resources(self):
elif tag_key == 'name':
name = tag.get('Value')
if not skip and user:
user = user.lower()
if user in self.__users_mapping_list:
user = self.__users_mapping_list[user]
instance_details = {'InstanceId': resource.get('InstanceId'),
'Name': name, 'LaunchDate': str(launch_time),
'RunningDays': f"{days} days",
'State': resource.get('State', {}).get('Name'),
'InstanceType': resource.get('InstanceType')}
if ticket_tags: # Add TicketId tags if available
instance_details['TicketId'] = ticket_tags
long_running_instances_by_user.setdefault(user.lower(), {}).setdefault(region_name,
[]).append(
long_running_instances_by_user.setdefault(user, {}).setdefault(region_name,
[]).append(
instance_details)
return long_running_instances_by_user

Expand All @@ -106,7 +126,6 @@ def organize_message_to_send_slack(self, resources_list: dict):
"""

divider = {"type": "divider"}
keys_list = ['User', 'TicketId', 'Region', 'Name', 'InstanceType', 'InstanceId', 'LaunchDate', 'RunningDays']
rows = []
for user, region_list in resources_list.items():
for region_name, resources_list in region_list.items():
Expand All @@ -115,12 +134,36 @@ def organize_message_to_send_slack(self, resources_list: dict):
resources.update({'User': user, 'Region': region_name})
rows.append({
"type": "section",
"fields": [{"type": "mrkdwn", "text": f"{str(resources.get(item))}"} for item in keys_list],
})
"fields": [
{"type": "mrkdwn", "text": f"{str(resources.get(item))}"}
if item != 'User' else {"type": "mrkdwn", "text": f"@{str(resources.get(item))}"}
for item in self.KEYS_LIST]}
)
rows.append(divider)
item_blocks = [rows[i:i + self.SLACK_ITEM_SIZE] for i in
range(0, len(rows), self.SLACK_ITEM_SIZE)] # splitting because slack block allows only 50 items
slack_message_block = []
slack_message_block = [[{
"type": "rich_text",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"type": "text",
"text": "Please look at the following instances and take an respective action",
"style": {
"bold": True
},
}
]
}
]
}], [{
'type': 'section',
'fields': [
{"type": "mrkdwn", "text": f"{item}"} for item in self.KEYS_LIST
]
}]]
for block in item_blocks:
slack_message_block.append(block)
return slack_message_block
Expand All @@ -131,11 +174,9 @@ def organize_message_to_seng_mail(self, resources_list: dict):
:param resources_list:
:return:
"""
keys_list = ['User', 'TicketId', 'Region', 'Name', 'InstanceType', 'InstanceId', 'LaunchDate', 'State',
'RunningDays']
with open('email_template.j2') as template:
template = Template(template.read())
body = template.render({'resources_list': resources_list, 'keys_list': keys_list})
body = template.render({'resources_list': resources_list, 'keys_list': self.KEYS_LIST})
return body


Expand Down Expand Up @@ -199,25 +240,31 @@ def lambda_handler(event, context):
ec2_operations = EC2Operations()
account_name = ec2_operations.get_account_alias_name()
process_data = ProcessData(subject=f'Daily Cloud Report: Long running instances in the @{account_name} account')
slack_message = ''
if os.environ.get("SLACK_API_TOKEN"):
slack_blocks = ec2_operations.organize_message_to_send_slack(ec2_operations.get_resources())
code, message = process_data.post_message_in_slack(slack_blocks=slack_blocks, account_name=account_name)
slack_message = message
organized_ec2_data = ec2_operations.organize_message_to_seng_mail(ec2_operations.get_resources())
if os.environ.get("SEND_AGG_MAIL", "no").lower() == "yes":
code, message = process_data.save_to_elastic_search(organized_ec2_data, account_name=account_name)
if os.environ.get('SES_HOST_ADDRESS'):
code, message = process_data.send_email(organized_ec2_data)
elif os.environ.get('SES_HOST_ADDRESS'):
if os.environ.get('SES_HOST_ADDRESS'):
code, message = process_data.send_email(organized_ec2_data)
else:
organized_ec2_data = ec2_operations.organize_message_to_seng_mail(ec2_operations.get_resources())
if os.environ.get("SEND_AGG_MAIL", "no").lower() == "yes":
code, message = process_data.save_to_elastic_search(organized_ec2_data, account_name=account_name)
if os.environ.get('SES_HOST_ADDRESS'):
code, message = process_data.send_email(organized_ec2_data)
elif os.environ.get('SES_HOST_ADDRESS'):
if os.environ.get('SES_HOST_ADDRESS'):
code, message = process_data.send_email(organized_ec2_data)
else:
if not os.environ.get('SES_HOST_ADDRESS') and \
not os.environ.get("SEND_AGG_MAIL", "no").lower() == "yes" and \
not os.environ.get("SLACK_API_TOKEN"):
organized_ec2_data = ec2_operations.get_resources()
message = organized_ec2_data
code = 200
end_time = time()
return {
'statusCode': code,
'body': json.dumps({'message': message, 'extra_message': extra_message}),
'body': json.dumps({'message': message,
'extra_message': extra_message,
'slack_message': slack_message}),
'total_running_time': f"{end_time - start_time} s"
}