import boto3
from botocore.exceptions import ClientError
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import datetime
import os
import sys     #required for system functions (exiting, in this case)

AWS_REGION = 'eu-west-1'

# Set up resource calls
ec2 = boto3.resource('ec2')
s3 = boto3.resource('s3')
rds = boto3.client('rds')
iam = boto3.client('iam')
ses = boto3.client('ses',region_name=AWS_REGION)

#Email settings
SENDER = '<EMAIL>'
RECIPIENT = '<EMAIL>'
SUBJECT = "AWS Monthly Report"
BODY = SUBJECT + '\n'
CHARSET = "UTF-8"

filepath = '/tmp/monthly.csv'


#Set up email server using AWS SMPTP

def mail(RECIPIENT, SENDER, SUBJECT, BODY, attach, alias):
    msg = MIMEMultipart('mixed')
    msg['Subject'] = SUBJECT 
    msg['From'] = SENDER 
    msg['To'] = RECIPIENT
    msg_body = MIMEMultipart('alternative')
    textpart = MIMEText(BODY.encode(CHARSET), 'plain', CHARSET)
    msg_body.attach(textpart)
    
    att = MIMEApplication(open(filepath, 'rb').read())
    att.add_header('Content-Disposition','attachment',filename="{}.csv".format(alias))
    if os.path.exists(filepath):
        print("File exists")
    else:
        print("File does not exists")
       
    msg.attach(msg_body)
    msg.attach(att)
    try:
    #Provide the contents of the email.
        response = ses.send_raw_email(
            Source=msg['From'],
            Destinations=[
                msg['To']
            ],
            RawMessage={
                'Data':msg.as_string(),
            }
        )
    except ClientError as e:
        return(e.response['Error']['Message'])
    else:
        return("Email sent! Message ID:", response['MessageId'])
       
def servers():  # Write instance tags to file

    instances = ec2.instances.all()
    
    #Open local file to write
    f = open(filepath, 'w')
    f.write("Name, Type, Size, Platform, CreationDate, CostCentre, Quadrant, State, Description, Encryption\n")
    
    for i in instances:
        processerr = 'false'
        try:
            for tag in i.tags:
                    try:
                        name = (item for item in i.tags if item["Key"] == "Name" ).__next__()
                    except StopIteration:
                        name['Value'] = 'Unknown'
                        print ("Name Unknown - {}".format(i.id))
                        
                    try:
                        createdate = (item for item in i.tags if item["Key"] == "CreationDate" ).__next__()
                    except StopIteration:
                        createdate['Value'] = 'Unknown'
                        print ("CreationDate Unknown - {}".format(i.id))
    
                    try:
                        costcentre  = (item for item in i.tags if item["Key"] == "CostCentre" ).__next__()
                    except StopIteration:
                        costcentre['Value'] = 'Unknown'
                        print ("CostCentre Unknown - {}".format(i.id))
                    
                    try:
                        quadrant = (item for item in i.tags if item["Key"] == "Quadrant" ).__next__()
                    except StopIteration:
                        quadrant['Value'] = 'Unknown'
                        print ("Quadrant Unknown - {}".format(i.id))
                    
                    try:
                        description = (item for item in i.tags if item["Key"] == "Description" ).__next__()
                    except StopIteration:
                        description['Value'] = 'Unknown'
                        print ("Description Unknown - {}".format(i.id))
        except:
            print ("exception - {}".format(i.id))
            processerr = 'true'

        EC2 = 'EC2'
        if processerr == 'false':
            f.write('%s,%s,%s,%s,%s,%s,%s,%s, %s\n' %(name['Value'], EC2, i.instance_type, i.platform, createdate['Value'], costcentre['Value'], quadrant['Value'], i.state['Name'], description['Value']))
        else:
            print (i)
        
def databases(): # Write DB instance tags to file
    
        #Open local file to write
    f = open(filepath, 'a')

    databases = rds.describe_db_instances()
    for db in databases['DBInstances']:
        processdberr = 'false'
        try:
            dbname = db['DBInstanceIdentifier']
            dbsize = db['DBInstanceClass']
            dbengine = db['Engine']
            dbstatus = db['DBInstanceStatus']
            dbcreatedate = db['InstanceCreateTime'].strftime("%Y-%m-%d")
            dbencryption = db['StorageEncrypted']
    
            
            currentdb = db['DBInstanceArn']
            taglist = rds.list_tags_for_resource(ResourceName = currentdb)['TagList']
            
            for tag in taglist:
                try:
                    dbcostcentre  = (item for item in taglist if item["Key"] == "CostCentre" ).__next__()
                except:
                    dbcostcentre['Value'] = 'Unknown'
                    
            for tag in taglist:
                try:
                    dbquadrant  = (item for item in taglist if item["Key"] == "Quadrant" ).__next__()
                except:
                    dbquadrant['Value'] = 'Unknown'
                    
            for tag in taglist:
                try:
                    dbdescription  = (item for item in taglist if item["Key"] == "Description" ).__next__()
                except:
                    dbdescription['Value'] = 'Unknown'
        except:
            print ("exception - {}".format(dbname))
            processdberr = 'true'
        if processdberr == 'false':            
            RDS = 'RDS'
            f.write('%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n' %(dbname, RDS, dbsize, dbengine, dbcreatedate, dbcostcentre['Value'], dbquadrant['Value'], dbstatus, dbdescription['Value'], dbencryption))
        else:
            print (dbname)
            
def lambda_handler(event, context):
    
    # Get Account Name

    paginator = iam.get_paginator('list_account_aliases')
    for response in paginator.paginate():
        alias = (response['AccountAliases'][0])
        
    SUBJECT = "AWS Monthly Report - " + alias
    
    servers()
    databases()

    # Send emails
    mail(RECIPIENT, SENDER, SUBJECT, BODY, filepath, alias)
    print ("Email sent")

import boto3
from botocore.exceptions import ClientError
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import datetime
import os
import sys     #required for system functions (exiting, in this case)

AWS_REGION = 'eu-west-1'

# Set up resource calls
ec2 = boto3.resource('ec2')
s3 = boto3.resource('s3')
rds = boto3.client('rds')
iam = boto3.client('iam')
ses = boto3.client('ses',region_name=AWS_REGION)

#Email settings
SENDER = '<EMAIL>'
RECIPIENT = '<EMAIL>'
SUBJECT = "AWS Monthly Report"
BODY = SUBJECT + '\n'
CHARSET = "UTF-8"

filepath = '/tmp/monthly.csv'


#Set up email server using AWS SMPTP

def mail(RECIPIENT, SENDER, SUBJECT, BODY, attach, alias):
    msg = MIMEMultipart('mixed')
    msg['Subject'] = SUBJECT 
    msg['From'] = SENDER 
    msg['To'] = RECIPIENT
    msg_body = MIMEMultipart('alternative')
    textpart = MIMEText(BODY.encode(CHARSET), 'plain', CHARSET)
    msg_body.attach(textpart)
    
    att = MIMEApplication(open(filepath, 'rb').read())
    att.add_header('Content-Disposition','attachment',filename="{}.csv".format(alias))
    if os.path.exists(filepath):
        print("File exists")
    else:
        print("File does not exists")
       
    msg.attach(msg_body)
    msg.attach(att)
    try:
    #Provide the contents of the email.
        response = ses.send_raw_email(
            Source=msg['From'],
            Destinations=[
                msg['To']
            ],
            RawMessage={
                'Data':msg.as_string(),
            }
        )
    except ClientError as e:
        return(e.response['Error']['Message'])
    else:
        return("Email sent! Message ID:", response['MessageId'])
       
def servers():  # Write instance tags to file

    instances = ec2.instances.all()
    
    #Open local file to write
    f = open(filepath, 'w')
    f.write("Name, Type, Size, Platform, CreationDate, CostCentre, Quadrant, State, Description, Encryption\n")
    
    for i in instances:
        processerr = 'false'
        try:
            for tag in i.tags:
                    try:
                        name = (item for item in i.tags if item["Key"] == "Name" ).__next__()
                    except StopIteration:
                        name['Value'] = 'Unknown'
                        print ("Name Unknown - {}".format(i.id))
                        
                    try:
                        createdate = (item for item in i.tags if item["Key"] == "CreationDate" ).__next__()
                    except StopIteration:
                        createdate['Value'] = 'Unknown'
                        print ("CreationDate Unknown - {}".format(i.id))
    
                    try:
                        costcentre  = (item for item in i.tags if item["Key"] == "CostCentre" ).__next__()
                    except StopIteration:
                        costcentre['Value'] = 'Unknown'
                        print ("CostCentre Unknown - {}".format(i.id))
                    
                    try:
                        quadrant = (item for item in i.tags if item["Key"] == "Quadrant" ).__next__()
                    except StopIteration:
                        quadrant['Value'] = 'Unknown'
                        print ("Quadrant Unknown - {}".format(i.id))
                    
                    try:
                        description = (item for item in i.tags if item["Key"] == "Description" ).__next__()
                    except StopIteration:
                        description['Value'] = 'Unknown'
                        print ("Description Unknown - {}".format(i.id))
        except:
            print ("exception - {}".format(i.id))
            processerr = 'true'

        EC2 = 'EC2'
        if processerr == 'false':
            f.write('%s,%s,%s,%s,%s,%s,%s,%s, %s\n' %(name['Value'], EC2, i.instance_type, i.platform, createdate['Value'], costcentre['Value'], quadrant['Value'], i.state['Name'], description['Value']))
        else:
            print (i)
        
def databases(): # Write DB instance tags to file
    
        #Open local file to write
    f = open(filepath, 'a')

    databases = rds.describe_db_instances()
    for db in databases['DBInstances']:
        processdberr = 'false'
        try:
            dbname = db['DBInstanceIdentifier']
            dbsize = db['DBInstanceClass']
            dbengine = db['Engine']
            dbstatus = db['DBInstanceStatus']
            dbcreatedate = db['InstanceCreateTime'].strftime("%Y-%m-%d")
            dbencryption = db['StorageEncrypted']
    
            
            currentdb = db['DBInstanceArn']
            taglist = rds.list_tags_for_resource(ResourceName = currentdb)['TagList']
            
            for tag in taglist:
                try:
                    dbcostcentre  = (item for item in taglist if item["Key"] == "CostCentre" ).__next__()
                except:
                    dbcostcentre['Value'] = 'Unknown'
                    
            for tag in taglist:
                try:
                    dbquadrant  = (item for item in taglist if item["Key"] == "Quadrant" ).__next__()
                except:
                    dbquadrant['Value'] = 'Unknown'
                    
            for tag in taglist:
                try:
                    dbdescription  = (item for item in taglist if item["Key"] == "Description" ).__next__()
                except:
                    dbdescription['Value'] = 'Unknown'
        except:
            print ("exception - {}".format(dbname))
            processdberr = 'true'
        if processdberr == 'false':            
            RDS = 'RDS'
            f.write('%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n' %(dbname, RDS, dbsize, dbengine, dbcreatedate, dbcostcentre['Value'], dbquadrant['Value'], dbstatus, dbdescription['Value'], dbencryption))
        else:
            print (dbname)
            
def lambda_handler(event, context):
    
    # Get Account Name

    paginator = iam.get_paginator('list_account_aliases')
    for response in paginator.paginate():
        alias = (response['AccountAliases'][0])
        
    SUBJECT = "AWS Monthly Report - " + alias
    
    servers()
    databases()

    # Send emails
    mail(RECIPIENT, SENDER, SUBJECT, BODY, filepath, alias)
    print ("Email sent")

#required for system functions (exiting, in this case) # Set up resource calls #Email settings #Set up email server using AWS SMPTP #Provide the contents of the email. # Write instance tags to file #Open local file to write # Write DB instance tags to file #Open local file to write # Get Account Name # Send emails