Для взаимодействия с облачной инфраструктурой AWS компания Amazon поддерживает открытый проект на GitHub, который реализует Python SDK. С помощью библиотек из этого проекта можно реализовать взаимодействие с облачной инфраструктурой посредством скриптов или даже написать собственный облегченный веб-сервис для AWS. Полная документация к библиотекам опубликована в библиотеке Amazon.
print('--- importing module_aws.py ---') # импортирование модулей, установленных в системе from boto3 import client as aws_client from botocore.config import Config from datetime import datetime, timedelta from os import path as os_path from os import getcwd as os_getcwd from os import environ as os_environ from sys import path as sys_path # импортирование модулей из проекта try: print(' trying to import modules with relative paths') from .module_core import instances_json_read from django.conf import settings print(' relative import is OK') except ImportError: print(' relative import failed') print(' trying to import modules with absolute paths') try: # получение текущей дирректории, откуда запущен скрипт - должен быть корень проекта current_directory = os_getcwd() # добавление пути к папке проекта в переменные среды sys_path.append(current_directory) # подключение настроек проекта os_environ.setdefault('DJANGO_SETTINGS_MODULE', 'webconsole.settings') # импортирование переменных Django в текущую среду from django.conf import settings from module_core import instances_json_read print(' absolute import is OK') except ModuleNotFoundError: print(' absolute import failed') exit() print() aws_access_key_id = settings.AWS_ACCESS_KEY aws_secret_access_key = settings.AWS_SECRET_KEY region_name = settings.AWS_REGION proxies = settings.PROXY_SETTINGS['proxies'] aws_ec2_types = settings.AWS_EC2_TYPES def aws_ec2_client(aws_access_key_id, aws_secret_access_key, region_name, proxies): client = aws_client( 'ec2', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=region_name, config=Config(proxies=proxies), ) return client def aws_cloudwatch_client(aws_access_key_id, aws_secret_access_key, region_name, proxies): client = aws_client( 'cloudwatch', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=region_name, config=Config(proxies=proxies), ) return client def aws_instance_properties_local(id): # путь к json-файлу instances_filepath = os_path.join(settings.BASE_DIR, settings.PROJECT_INSTANCES_JSON_FILEPATH) # запрос данных из json-файла try: instances_table = instances_json_read(instances_filepath)['aws_vm_table'] instance_line = instances_table.loc[id.lower()].to_dict() except: instance_line = '' return instance_line def aws_instance_properties_mixed(id): # получение локальных данных из файла vm_properties = aws_instance_properties_local(id) # получение облачных данных ec2_client = aws_ec2_client(aws_access_key_id, aws_secret_access_key, region_name, proxies) response = ec2_client.describe_instances(Filters=[{ 'Name': 'instance-id', 'Values': [id,] },]) instance_attr = response['Reservations'][0]['Instances'][0] tags = {} for item in instance_attr['Tags']: tags.update({item['Key']: item['Value']}) i_id = instance_attr['InstanceId'] # описание сервера i_description = '' if 'Description' in tags: i_description = tags['Description'] # назначение сервера i_purpose = '' if 'Description' in tags: i_purpose = tags['Purpose'] # расписание резервного копирования сервера i_backup = '' if 'cpm backup' in tags: i_backup = tags['cpm backup'] # расписание работы сервера i_schedule = '' if 'StartStopSchedule' in tags: i_schedule = tags['StartStopSchedule'] # список доступа к управлению питанием i_start_stop_access = '' if 'StartStopAccess' in tags: i_start_stop_access = tags['StartStopAccess'].lower() # состояние сервера i_state = instance_attr['State']['Name'] # построение словаря атрибутов curValues = { 'id': i_id, 'name': vm_properties['name'], 'type': vm_properties['type'], 'zone': vm_properties['vpc_description'], 'ip_address': vm_properties['ip_address'], 'responsible': vm_properties['responsible'], 'project': vm_properties['project'], 'description': i_description, 'purpose': i_purpose, 'state': i_state, 'backup': i_backup, 'schedule': i_schedule, 'schedule_description': '', 'start_stop_access': i_start_stop_access, } return curValues def aws_instance_start(vm_id): ec2_client = aws_ec2_client(aws_access_key_id, aws_secret_access_key, region_name, proxies) result = ec2_client.start_instances(InstanceIds=[vm_id,]) return result def aws_instance_stop(vm_id): ec2_client = aws_ec2_client(aws_access_key_id, aws_secret_access_key, region_name, proxies) result = ec2_client.stop_instances(InstanceIds=[vm_id,]) return result def aws_instance_save(vm_id, description, purpose, backup_name, schedule_name, start_stop_access): # построение коллекции тэгов update_tags = [] delete_tags = [] # заполнение тэгов update_tags.append({'Key': 'Description', 'Value': description},) update_tags.append({'Key': 'Purpose', 'Value': purpose},) if not (backup_name == ''): update_tags.append({'Key': 'cpm backup', 'Value': backup_name},) else: delete_tags.append({'Key': 'cpm backup',}) if not (schedule_name == ''): update_tags.append({'Key': 'StartStopSchedule', 'Value': schedule_name},) else: delete_tags.append({'Key': 'StartStopSchedule',}) if not (start_stop_access == ''): # заменить "," и пробелы на ";", преобразовать в строчные start_stop_access = start_stop_access.replace(' ',';').replace(',',';').lower() # преобразовать строку в список start_stop_access_list = start_stop_access.split(";") # удалить пустые элементы start_stop_access_list = list(filter(None, start_stop_access_list)) # удалить дубликаты из списка (преобразовать список в множество и обратно в список) start_stop_access_list = list(set(start_stop_access_list)) # сортировка списка start_stop_access_list.sort() # преобразовать список в строку start_stop_access = ';'.join(start_stop_access_list) update_tags.append({'Key': 'StartStopAccess', 'Value': start_stop_access},) else: delete_tags.append({'Key': 'StartStopAccess',}) # создание клиента подключения к AWS EC2 ec2_client = aws_ec2_client(aws_access_key_id, aws_secret_access_key, region_name, proxies) # выполнение запроса на удаление тэгов в AWS EC2 if len(delete_tags) > 0 : result = ec2_client.delete_tags( Resources=[vm_id,], Tags=delete_tags, ) # выполнение запроса на обновление тэгов в AWS EC2 if len(update_tags) > 0 : result = ec2_client.create_tags( Resources=[vm_id,], Tags=update_tags, ) return def aws_instance_metrics(vm_id): import pandas as pd cw_client = aws_cloudwatch_client(aws_access_key_id, aws_secret_access_key, region_name, proxies) time_start = datetime.utcnow() - timedelta(hours=8) time_stop = datetime.utcnow() vm_properties = aws_instance_properties_local(vm_id) response = cw_client.get_metric_statistics( Namespace='AWS/EC2', MetricName='CPUUtilization', StartTime=time_start, EndTime=time_stop, Statistics=['Maximum'], Period=300, Dimensions=[ { 'Name': 'InstanceId', 'Value': vm_id }, ], ) json_data = response['Datapoints'] if len(json_data) > 0: res_table = pd.json_normalize(json_data) res_table.sort_values(['Timestamp'], ascending=[True], inplace=True) res_table['Time'] = res_table['Timestamp'].apply(lambda x: (x+timedelta(hours=1)).strftime('%H:%M')) res_table.set_index('Timestamp', inplace=True) # переименование колонок в таблице res_table.rename(inplace=True, columns={'Maximum': 'CPU'}) if ('ws' in vm_properties['name']): response = cw_client.get_metric_statistics( Namespace='AGC/Windows', MetricName='Memory Physical Available', StartTime=time_start, EndTime=time_stop, Statistics=['Maximum'], Period=300, Dimensions=[ { 'Name': 'InstanceId', 'Value': vm_id }, { 'Name': 'instance', 'Value': '_Total', }, { 'Name': 'objectname', 'Value': 'Memory', }, ], ) json_data = response['Datapoints'] if len(json_data) > 0: ram_table = pd.json_normalize(json_data) ram_table.rename(inplace=True, columns={'Maximum': 'RAM'}) ram_table.set_index('Timestamp', inplace=True) res_table = res_table.join(ram_table,rsuffix='_r') # конвертирование доступной памяти из байт в мегабайт res_table['RAM'] = res_table['RAM'] / 1048576 if (vm_properties['type'] in aws_ec2_types): # получение размера памяти и конвертирование из гигабайтов в магабайты vm_ram = aws_ec2_types[vm_properties['type']]['ram'] * 1024 else: vm_ram = 0 # вычислеине используемой памяти в процентах res_table['RAM'] = round((vm_ram - res_table['RAM']) / vm_ram * 100) else: res_table['RAM'] = 0 else: response = cw_client.get_metric_statistics( Namespace='AGC/Linux', MetricName='Memory Utilization Percent', StartTime=time_start, EndTime=time_stop, Statistics=['Maximum'], Period=300, Dimensions=[ { 'Name': 'InstanceId', 'Value': vm_id }, ], ) json_data = response['Datapoints'] if len(json_data) > 0: ram_table = pd.json_normalize(json_data) ram_table.rename(inplace=True, columns={'Maximum': 'RAM'}) ram_table.set_index('Timestamp', inplace=True) res_table = res_table.join(ram_table,rsuffix='_r') else: res_table['RAM'] = 0 res_table = res_table.fillna(0) result = res_table[['Time', 'CPU', 'RAM']].values.tolist() else: result = '' return result if __name__ == '__main__': print(datetime.today()) result = aws_instance_metrics('i-1234567890abcdef') print(result)