Python функция повторения вывода на основе содержимого списка - PullRequest
0 голосов
/ 10 января 2020

У меня есть python функция, которая перечисляет серверы в AWS EC2.

По какой-то причине он повторяет одну и ту же информацию о сервере (тот же ID экземпляра, IP-адреса и т. Д. c) для каждого региона, который это проходит через Проблема в том, что каждый регион должен быть уникальным и иметь свои собственные серверы с различной информацией.

Если у меня есть один регион в этом списке, серверы перечислены один раз:

regions = ['us-east-1']

Если у меня есть два региона в списке одна и та же информация повторяется дважды:

regions = ['us-east-1', 'us-east-2']

Если у меня три региона, одна и та же информация повторяется 3 раза и так далее ...

Это моя функция:

def list_instances(aws_account,aws_account_number, interactive, regions, fieldnames, show_details):
    today, aws_env_list, output_file, output_file_name, fieldnames = initialize(interactive, aws_account)
    options = arguments()
    instance_list = ''
    session = ''
    ec2 = ''
    account_found = ''
    PrivateDNS = None
    block_device_list = None
    instance_count = 0
    account_type_message = ''
    profile_missing_message = ''
    region = ''
    # Set the ec2 dictionary
    ec2info = {}
    # Write the file headers
    if interactive == 1:
        with open(output_file, mode='w+') as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=',', lineterminator='\n')
            writer.writeheader()
    session = boto3.Session(profile_name=aws_account,region_name=region)
    print(Fore.CYAN)      
    report_gov_or_comm(aws_account, account_found)
    print(Fore.RESET)
    session = boto3.Session(profile_name=aws_account)
    account_found = 'yes'
    ec2 = session.client("ec2")
    for i in range(len(regions)):
        session = boto3.Session(profile_name=aws_account, region_name=region[i])
        print(f"*****Region: {region}*******")
        # Loop through the instances
        try:
            instance_list = ec2.describe_instances()
        except Exception as e:
                pass
        try:
            for reservation in instance_list["Reservations"]:
                for instance in reservation.get("Instances", []):
                    instance_count = instance_count + 1
                    launch_time = instance["LaunchTime"]
                    launch_time_friendly = launch_time.strftime("%B %d %Y")
                    tree = objectpath.Tree(instance)
                    block_devices = set(tree.execute('$..BlockDeviceMappings[\'Ebs\'][\'VolumeId\']'))
                    if block_devices:
                        block_devices = list(block_devices)
                        block_devices = str(block_devices).replace('[','').replace(']','').replace('\'','')
                    else:
                        block_devices = None
                    private_ips =  set(tree.execute('$..PrivateIpAddress'))
                    if private_ips:
                        private_ips_list = list(private_ips)
                        private_ips_list = str(private_ips_list).replace('[','').replace(']','').replace('\'','')
                    else:
                        private_ips_list = None
                    type(private_ips_list)
                    public_ips =  set(tree.execute('$..PublicIp'))
                    if len(public_ips) == 0:
                        public_ips = None
                    if public_ips:
                        public_ips_list = list(public_ips)
                        public_ips_list = str(public_ips_list).replace('[','').replace(']','').replace('\'','')
                    else:
                        public_ips_list = None
                    if 'KeyName' in instance:
                        key_name = instance['KeyName']
                    else:
                        key_name = None
                    name = None
                    if 'Tags' in instance:
                        try:
                            tags = instance['Tags']
                            name = None
                            for tag in tags:
                                if tag["Key"] == "Name":
                                    name = tag["Value"]
                                if tag["Key"] == "Engagement" or tag["Key"] == "Engagement Code":
                                    engagement = tag["Value"]
                        except ValueError:
                            # print("Instance: %s has no tags" % instance_id)
                            pass
                    if 'VpcId' in instance:
                        vpc_id = instance['VpcId']
                    else:
                        vpc_id = None
                    if 'PrivateDnsName' in instance:
                        private_dns = instance['PrivateDnsName']
                    else:
                        private_dns = None
                    ec2info[instance['InstanceId']] = {
                        'AWS Account': aws_account,
                        'Account Number': aws_account_number,
                        'Name': name,
                        'Instance ID': instance['InstanceId'],
                        'Volumes': block_devices,
                        'Private IP': private_ips_list,
                        'Public IP': public_ips_list,
                        'Private DNS': private_dns,
                        'Availability Zone': instance['Placement']['AvailabilityZone'],
                        'VPC ID': vpc_id,
                        'Type': instance['InstanceType'],
                        'Key Pair Name': key_name,
                        'State': instance['State']['Name'],
                        'Launch Date': launch_time_friendly
                    }
                    with open(output_file,'a') as csv_file:
                        writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=',', lineterminator='\n')
                        writer.writerow({'AWS Account': aws_account, "Account Number": aws_account_number, 'Name': name, 'Instance ID': instance["InstanceId"], 'Volumes': block_devices,  'Private IP': private_ips_list, 'Public IP': public_ips_list, 'Private DNS': private_dns, 'Availability Zone': instance['Placement']['AvailabilityZone'], 'VPC ID': vpc_id, 'Type': instance["InstanceType"], 'Key Pair Name': key_name, 'State': instance["State"]["Name"], 'Launch Date': launch_time_friendly})
                    ec2_info_items = ec2info.items
                    if show_details == 'y' or show_details == 'yes':
                        for instance_id, instance in ec2_info_items():
                            if account_found == 'yes':
                                print(Fore.RESET + "-------------------------------------")
                                for key in [
                                    'AWS Account',
                                    'Account Number',
                                    'Name',
                                    'Instance ID',
                                    'Volumes',
                                    'Private IP',
                                    'Public IP',
                                    'Private DNS',
                                    'Availability Zone',
                                    'VPC ID',
                                    'Type',
                                    'Key Pair Name',
                                    'State',
                                    'Launch Date'
                                ]:
                                    print(Fore.GREEN + f"{key}: {instance.get(key)}")
                                print(Fore.RESET + "-------------------------------------")
                        else:
                            pass
                    reservation = {}
                    instance = {}
                    ec2_info_items = {}
                    ec2info = {}
                    with open(output_file,'a') as csv_file:
                        csv_file.close()
        except Exception as e:
            print(f"An exception has occurred: {e}")
    if profile_missing_message == '*':
        banner(profile_missing_message)
    print(Fore.GREEN)
    report_instance_stats(instance_count, aws_account, account_found)
    print(Fore.RESET + '\n')
    #breakpoint()
    return output_file

def main():
    aws_account = 'us-account-1'
    aws_account_number = '123456789101'
    regions = ['us-east-1', 'us-east-2']
    show_details = 'yes'
    output_file = list_instances(aws_account,aws_account_number, interactive, regions, fieldnames, show_details)

if __name__ == __main__:
    main()

Я попытался сбросить некоторые значения в конце функции, чтобы она перестала повторять одну и ту же информацию снова и снова на основе содержимого списка regions. Но это не сработало!

        reservation = {}
        instance = {}
        ec2_info_items = {}
        ec2info = {}

Почему одна и та же информация повторяется снова и снова на основе содержимого списка regions?

1 Ответ

3 голосов
/ 10 января 2020

Проблема в том, что вы создали клиентский объект EC2 один раз для региона по умолчанию и никогда не обновляете его для других регионов.

Измените это:

ec2 = session.client("ec2")
for i in range(len(regions)):
    session = boto3.Session(profile_name=aws_account, region_name=region[i])
    print(f"*****Region: {region}*******")
    # Loop through the instances
    try:
        instance_list = ec2.describe_instances()

на это:

for region in regions:
    session = boto3.Session(profile_name=aws_account, region_name=region)
    ec2 = session.client("ec2")
    print(f"*****Region: {region}*******")
    # Loop through the instances
    try:
        instance_list = ec2.describe_instances()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...