#!/usr/bin/python3

# 
#   Copyright 2016 RIFT.IO Inc
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#


import os
import sys
import uuid
import rw_peas
from gi import require_version
require_version('RwCal', '1.0')

from gi.repository import RwcalYang
from gi.repository.RwTypes import RwStatus
import argparse
import logging
import rwlogger
import boto3
import botocore

persistent_resources = {
    'vms'      : [],
    'networks' : [],
}

MISSION_CONTROL_NAME = 'mission-control'
LAUNCHPAD_NAME = 'launchpad'

RIFT_IMAGE_AMI = 'ami-7070231a'

logging.basicConfig(level=logging.ERROR)
logger = logging.getLogger('rift.cal.awsresources')
logger.setLevel(logging.INFO)

def get_cal_plugin():
    """
        Load AWS cal plugin
    """
    plugin = rw_peas.PeasPlugin('rwcal_aws', 'RwCal-1.0')
    engine, info, extension = plugin()
    cal = plugin.get_interface("Cloud")
    rwloggerctx = rwlogger.RwLog.Ctx.new("Cal-Log")
    try:
        rc = cal.init(rwloggerctx)
        assert rc == RwStatus.SUCCESS
    except Exception as e:
        logger.error("ERROR:Cal plugin instantiation failed with exception %s",repr(e))
    else:
        logger.info("AWS Cal plugin successfully instantiated")
        return cal

def get_cal_account(**kwargs):
    """
    Returns AWS cal account
    """
    account                        = RwcalYang.YangData_RwProject_Project_CloudAccounts_CloudAccountList()
    account.account_type           = "aws"
    account.aws.key = kwargs['key']
    account.aws.secret = kwargs['secret']
    account.aws.region = kwargs['region']
    if 'ssh_key' in kwargs and kwargs['ssh_key'] is not None:
        account.aws.ssh_key = kwargs['ssh_key']
    account.aws.availability_zone = kwargs['availability_zone']
    if 'vpcid' in kwargs and kwargs['vpcid'] is not None: 
        account.aws.vpcid =  kwargs['vpcid']
    if 'default_subnet_id' in kwargs and kwargs['default_subnet_id'] is not None:
        account.aws.default_subnet_id = kwargs['default_subnet_id']
    return account

class AWSResources(object):
    """
    Class with methods to manage AWS resources
    """
    def __init__(self,**kwargs):
        self._cal      = get_cal_plugin()
        self._acct     = get_cal_account(**kwargs)

    def _destroy_vms(self):
        """
        Destroy VMs
        """
        logger.info("Initiating VM cleanup")
        rc, rsp = self._cal.get_vdu_list(self._acct)
        vdu_list = [vm for vm in rsp.vdu_info_list if vm.name not in persistent_resources['vms']]
        logger.info("Deleting VMs : %s" %([x.name for x in vdu_list]))

        for vdu in vdu_list:
            self._cal.delete_vdu(self._acct, vdu.vdu_id)

        logger.info("VM cleanup complete")

    def _destroy_networks(self):
        """
        Destroy Networks
        """
        logger.info("Initiating Network cleanup")
        driver = self._cal._get_driver(self._acct)
        subnets = driver.get_subnet_list()
        subnet_list = [subnet for subnet in subnets if subnet.default_for_az is False]

        logger.info("Deleting Networks : %s" %([x.id for x in subnet_list]))
        for subnet in subnet_list:
            self._cal.delete_virtual_link(self._acct, subnet.subnet_id)
        logger.info("Network cleanup complete")

    def destroy_resource(self):
        """
        Destroy resources
        """
        logger.info("Cleaning up AWS resources")
        self._destroy_vms()
        self._destroy_networks()
        logger.info("Cleaning up AWS resources.......[Done]")

    def _destroy_mission_control(self):
        """
        Destroy Mission Control VM
        """
        logger.info("Initiating MC VM cleanup")
        rc, rsp = self._cal.get_vdu_list(self._acct)
        vdu_list = [vm for vm in rsp.vdu_info_list if vm.name == MISSION_CONTROL_NAME]
        logger.info("Deleting VMs : %s" %([x.name for x in vdu_list]))

        for vdu in vdu_list:
            self._cal.delete_vdu(self._acct, vdu.vdu_id)
        logger.info("MC VM cleanup complete")

    def _destroy_launchpad(self):
        """
        Destroy Launchpad VM
        """
        logger.info("Initiating LP VM cleanup")
        rc, rsp = self._cal.get_vdu_list(self._acct)
        vdu_list = [vm for vm in rsp.vdu_info_list if vm.name == LAUNCHPAD_NAME]
        logger.info("Deleting VMs : %s" %([x.name for x in vdu_list]))

        for vdu in vdu_list:
            self._cal.delete_vdu(self._acct, vdu.vdu_id)
        logger.info("LP VM cleanup complete")
        

    def create_mission_control(self):
        """
        Create Mission Control VM in AWS
        """ 
        logger.info("Creating mission control VM")
        vdu = RwcalYang.YangData_RwProject_Project_VduInitParams()
        vdu.name = MISSION_CONTROL_NAME
        vdu.image_id = RIFT_IMAGE_AMI
        vdu.flavor_id = 'c3.large'
        vdu.allocate_public_address = True
        vdu.vdu_init.userdata = "#cloud-config\n\nruncmd:\n - echo Sleeping for 5 seconds and attempting to start salt-master\n - sleep 5\n - /bin/systemctl restart salt-master.service\n"

        rc,rs=self._cal.create_vdu(self._acct,vdu)
        assert rc == RwStatus.SUCCESS
        self._mc_id = rs

        driver = self._cal._get_driver(self._acct)
        inst=driver.get_instance(self._mc_id)
        inst.wait_until_running()

        rc,rs =self._cal.get_vdu(self._acct,self._mc_id, "")
        assert rc == RwStatus.SUCCESS
        self._mc_public_ip = rs.public_ip
        self._mc_private_ip = rs.management_ip
        
        logger.info("Started Mission Control VM with id %s and IP Address %s\n",self._mc_id, self._mc_public_ip)

    def create_launchpad_vm(self, salt_master = None):        
        """
        Create Launchpad VM in AWS
        Arguments
            salt_master (String): String with Salt master IP typically MC VM private IP
        """
        logger.info("Creating launchpad VM")
        USERDATA_FILENAME = os.path.join(os.environ['RIFT_INSTALL'],
                                 'etc/userdata-template')

        try:
            fd = open(USERDATA_FILENAME, 'r')
        except Exception as e:
                sys.exit(-1)
        else:
            LP_USERDATA_FILE = fd.read()
            # Run the enable lab script when the openstack vm comes up
            LP_USERDATA_FILE += "runcmd:\n"
            LP_USERDATA_FILE += " - echo Sleeping for 5 seconds and attempting to start elastic-network-interface\n"
            LP_USERDATA_FILE += " - sleep 5\n"
            LP_USERDATA_FILE += " - /bin/systemctl restart elastic-network-interfaces.service\n"

        if salt_master is None:
            salt_master=self._mc_private_ip
        node_id = str(uuid.uuid4())

        vdu = RwcalYang.YangData_RwProject_Project_VduInitParams()
        vdu.name = LAUNCHPAD_NAME
        vdu.image_id = RIFT_IMAGE_AMI
        vdu.flavor_id = 'c3.xlarge'
        vdu.allocate_public_address = True
        vdu.vdu_init.userdata = LP_USERDATA_FILE.format(master_ip = salt_master,
                                          lxcname = node_id)
        vdu.node_id = node_id

        rc,rs=self._cal.create_vdu(self._acct,vdu)
        assert rc == RwStatus.SUCCESS
        self._lp_id = rs

        driver = self._cal._get_driver(self._acct)
        inst=driver.get_instance(self._lp_id)
        inst.wait_until_running()

        rc,rs =self._cal.get_vdu(self._acct,self._lp_id, "")
        assert rc == RwStatus.SUCCESS

        self._lp_public_ip = rs.public_ip
        self._lp_private_ip = rs.management_ip
        logger.info("Started Launchpad VM with id %s and IP Address %s\n",self._lp_id, self._lp_public_ip)
         
    def upload_ssh_key_to_ec2(self):
        """
         Upload SSH key to EC2 region
        """
        driver = self._cal._get_driver(self._acct)
        key_name = os.getlogin() + '-' + 'sshkey' 
        key_path = '%s/.ssh/id_rsa.pub' % (os.environ['HOME'])
        if os.path.isfile(key_path):
            logger.info("Uploading ssh public key file in path %s with keypair name %s", key_path,key_name)
            with open(key_path) as fp:
                driver.upload_ssh_key(key_name,fp.read())
        else:
            logger.error("Valid Public key file %s not found", key_path)


def main():
    """
    Main routine
    """
    parser = argparse.ArgumentParser(description='Script to manage AWS resources')

    parser.add_argument('--aws-key',
                        action = 'store',
                        dest = 'aws_key',
                        type = str,
                        help='AWS key')

    parser.add_argument('--aws-secret',
                        action = 'store',
                        dest = 'aws_secret',
                        type = str,
                        help='AWS secret')

    parser.add_argument('--aws-region',
                        action = 'store',
                        dest = 'aws_region',
                        type = str,
                        help='AWS region')

    parser.add_argument('--aws-az',
                        action = 'store',
                        dest = 'aws_az',
                        type = str,
                        help='AWS Availability zone')

    parser.add_argument('--aws-sshkey',
                        action = 'store',
                        dest = 'aws_sshkey',
                        type = str,
                        help='AWS SSH Key to login to instance')

    parser.add_argument('--aws-vpcid',
                        action = 'store',
                        dest = 'aws_vpcid',
                        type = str,
                        help='AWS VPC ID to use to indicate non default VPC')

    parser.add_argument('--aws-default-subnet',
                        action = 'store',
                        dest = 'aws_default_subnet',
                        type = str,
                        help='AWS Default subnet id in VPC to be used for mgmt network')

    parser.add_argument('--mission-control',
                        action = 'store_true',
                        dest = 'mission_control',
                        help='Create Mission Control VM')

    parser.add_argument('--launchpad',
                        action = 'store_true',
                        dest = 'launchpad',
                        help='Create LaunchPad VM')

    parser.add_argument('--salt-master',
                        action = 'store',
                        dest = 'salt_master',
                        type = str,
                        help='IP Address of salt controller. Required, if only launchpad  VM is being created.')

    parser.add_argument('--cleanup',
                        action = 'store',
                        dest = 'cleanup',
                        nargs = '+',
                        type = str,
                        help = 'Perform resource cleanup for AWS installation. \n Possible options are {all, mc, lp,  vms, networks }')

    parser.add_argument('--upload-ssh-key',
                         action = 'store_true',
                         dest = 'upload_ssh_key',
                         help = 'Upload users SSH public key ~/.ssh/id_rsa.pub')  

    argument = parser.parse_args()

    if (argument.aws_key is None or argument.aws_secret is None or argument.aws_region is None or
       argument.aws_az is None):
        logger.error("Missing mandatory params. AWS Key, Secret, Region, AZ and SSH key are mandatory params")
        sys.exit(-1)

    if (argument.cleanup is None and argument.mission_control is None and argument.launchpad is None 
        and argument.upload_ssh_key is None):
        logger.error('Insufficient parameters')
        sys.exit(-1)

    ### Start processing
    logger.info("Instantiating cloud-abstraction-layer")
    drv = AWSResources(key=argument.aws_key, secret=argument.aws_secret, region=argument.aws_region, availability_zone = argument.aws_az, 
                       ssh_key = argument.aws_sshkey, vpcid = argument.aws_vpcid, default_subnet_id = argument.aws_default_subnet)
    logger.info("Instantiating cloud-abstraction-layer.......[Done]")

    if argument.upload_ssh_key:
         drv.upload_ssh_key_to_ec2()

    if argument.cleanup is not None:
        for r_type in argument.cleanup:
            if r_type == 'all':
                drv.destroy_resource()
                break
            if r_type == 'vms':
                drv._destroy_vms()
            if r_type == 'networks':
                drv._destroy_networks()
            if r_type == 'mc':
                drv._destroy_mission_control()
            if r_type == 'lp':
                drv._destroy_launchpad()

    if argument.mission_control == True:
        drv.create_mission_control()

    if argument.launchpad == True:
        if argument.salt_master is None and argument.mission_control is False:
            logger.error('Salt Master IP address not provided to start Launchpad.')
            sys.exit(-2)

        drv.create_launchpad_vm(argument.salt_master)

if __name__ == '__main__':
    main()
