Как добавить новую строку в существующий файл CSV в Python? - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь написать скрипт Python, который бы создавал CSV-файл с первой строкой в ​​виде имен тегов экземпляра AWS EC2 из всех учетных записей. Затем он заполнит этот CSV-файл соответствующими значениями тегов из всех экземпляров. Я могу создать заголовок файла CSV, а также может генерировать строки, состоящие из значений. Я считаю, что в коде я пытаюсь правильно добавить строку. Я вставил свой полный код ниже. Пожалуйста, советуйте. Спасибо.

Я верю, что в коде, в этом конкретном месте, я делаю некоторую ошибку:

                with open(output_file, 'a', newline='') as f:
                    writer = csv.writer(f)
                    writer.writerow(row)
                    #print(row)
                    #sys.exit()
                    #pass
#!/usr/bin/env python

import boto3
import botocore
import argparse
import csv
import logging
import datetime
import click
import yaml
import os
import time
import sys

logging.basicConfig(filename='tag-export.log', filemode='a', format='%(levelname)s - %(message)s')
logger = logging.getLogger()
logger.setLevel(logging.INFO)

targetaccount = 'allaccounts'

# GLOBAL SESSION
sts = boto3.client('sts')

def aws_session(account_id, session_name, role_name):
    """
    Function that creates the boto3 session by assuming a cross account role

    Uses boto3 to make calls to the STS API


def account_name(session):
    """
    Function that resolves the account name (alias) to make output human friendly

    Uses boto3 to make calls to the IAM API

def get_instances(filters=[]):
    reservations = {}
    try:
        reservations = ec2.describe_instances(
            Filters=filters
        )
    except botocore.exceptions.ClientError as e:
        print(e.response['Error']['Message'])

    instances = []
    for reservation in reservations.get('Reservations', []):
        for instance in reservation.get('Instances', []):
            instances.append(instance)
    return instances

@click.command()
@click.option('--config_file', required=True, prompt=True, default=lambda: str(os.getcwd()) + '/config.yml', show_default='config.yml')

def main(config_file):
    try:
        with open(config_file, 'r') as ymlfile:
            config = yaml.load(ymlfile)
        ymlfile.close()
    except Exception as e:
        logger.error('Unable to open config file: ' + str(e))
        exit    

    # globals
    if 'accounts' in config:
        accounts = config['accounts']
    if 'role_name' in config:
        role_name = config['role_name']


    tag_set = []
    for account in accounts:
        logger.info('dispatching session call for account: ' + str(account) )
        if str(account) == str(config['sourceaccount']):
            session = boto3.Session(region_name=config['region'])
        else:
            session = aws_session(account_id=str(account), session_name='cross-account-assume-role', role_name = role_name)
        if session:
            AccountName = account_name(session)
            logger.info('Working on account:  ' + AccountName)
            print('Working on gathering tags and sorting them.....Wait...:  ')
            global ec2
            ec2 = session.client('ec2', region_name='ap-southeast-2')
            output_file = "{}-tags.csv".format(targetaccount)
            instances = get_instances()

            for instance in instances:
                for tag in instance.get('Tags', []):
                    if tag.get('Key'):
                        tag_set.append(tag.get('Key'))
            tag_set = sorted(list(set(tag_set)))
        else:
            print("did not get session")
            sys.exit()            

    if tag_set:
        print ('Tag Gathering Completed! Moving to each account to get Tag Values')
        #sys.exit()

    with open(output_file, 'a', newline='') as csvfile:
        fieldnames = ['Account'] + ['InstanceId'] + tag_set
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames,extrasaction='ignore')
        writer.writeheader()

    for account in accounts:
        if str(account) == str(config['sourceaccount']):
            session = boto3.Session(region_name=config['region'])
        else:
            session = aws_session(account_id=str(account), session_name='cross-account-assume-role', role_name = role_name)

        if session:
            AccountName = account_name(session)
            logger.info('Working on account:  ' + AccountName)
            print('Working on account:  ' + AccountName + '....')
            instances = get_instances()
            for instance in instances:
                row = {}
                row['Account'] = AccountName
                row['InstanceId'] = instance.get('InstanceId')
                #print (row)
                #sys.exit()
                for tag in instance.get('Tags', []):
                    for vtag in tag_set:
                       if vtag == tag.get('Key'):
                           #print (tag.get('Key'))
                           #print ('vtag=' + vtag)
                           #sys.exit()     
                           row[tag.get('Key')] = tag.get('Value')
                           #print(row)
                with open(output_file, 'a', newline='') as f:
                    writer = csv.writer(f)
                    writer.writerow(row)
                    #print(row)
                    #sys.exit()
                    #pass
        else:
            print("did not get session")                


if __name__ == "__main__":
    main()

1 Ответ

0 голосов
/ 09 мая 2019

Я решил эту проблему, изменив логику. Вместо того, чтобы делать все это одним куском. Сначала я создал словарь тегов, затем создал другой словарь из файла CSV, а затем записал все это одним фрагментом, как показано ниже:

           with open(output_file, 'a', newline='') as f:
                writer = csv.writer(f)
                writer.writerow(row)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...