# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
# Copyright (c) 2010 Chris Moyer http://coredumped.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

"""
High-level abstraction of an EC2 server
"""
from __future__ import with_statement
import boto.ec2
from boto.mashups.iobject import IObject
from boto.pyami.config import BotoConfigPath, Config
from boto.sdb.db.model import Model
from boto.sdb.db.property import StringProperty, IntegerProperty, BooleanProperty, CalculatedProperty
from boto.manage import propget
from boto.ec2.zone import Zone
from boto.ec2.keypair import KeyPair
import os, time, StringIO
from contextlib import closing
from boto.exception import EC2ResponseError

InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge',
                 'c1.medium', 'c1.xlarge',
                 'm2.2xlarge', 'm2.4xlarge']

class Bundler(object):

    def __init__(self, server, uname='root'):
        from boto.manage.cmdshell import SSHClient
        self.server = server
        self.uname = uname
        self.ssh_client = SSHClient(server, uname=uname)

    def copy_x509(self, key_file, cert_file):
        print '\tcopying cert and pk over to /mnt directory on server'
        self.ssh_client.open_sftp()
        path, name = os.path.split(key_file)
        self.remote_key_file = '/mnt/%s' % name
        self.ssh_client.put_file(key_file, self.remote_key_file)
        path, name = os.path.split(cert_file)
        self.remote_cert_file = '/mnt/%s' % name
        self.ssh_client.put_file(cert_file, self.remote_cert_file)
        print '...complete!'

    def bundle_image(self, prefix, size, ssh_key):
        command = ""
        if self.uname != 'root':
            command = "sudo "
        command += 'ec2-bundle-vol '
        command += '-c %s -k %s ' % (self.remote_cert_file, self.remote_key_file)
        command += '-u %s ' % self.server._reservation.owner_id
        command += '-p %s ' % prefix
        command += '-s %d ' % size
        command += '-d /mnt '
        if self.server.instance_type == 'm1.small' or self.server.instance_type == 'c1.medium':
            command += '-r i386'
        else:
            command += '-r x86_64'
        return command

    def upload_bundle(self, bucket, prefix, ssh_key):
        command = ""
        if self.uname != 'root':
            command = "sudo "
        command += 'ec2-upload-bundle '
        command += '-m /mnt/%s.manifest.xml ' % prefix
        command += '-b %s ' % bucket
        command += '-a %s ' % self.server.ec2.aws_access_key_id
        command += '-s %s ' % self.server.ec2.aws_secret_access_key
        return command

    def bundle(self, bucket=None, prefix=None, key_file=None, cert_file=None,
               size=None, ssh_key=None, fp=None, clear_history=True):
        iobject = IObject()
        if not bucket:
            bucket = iobject.get_string('Name of S3 bucket')
        if not prefix:
            prefix = iobject.get_string('Prefix for AMI file')
        if not key_file:
            key_file = iobject.get_filename('Path to RSA private key file')
        if not cert_file:
            cert_file = iobject.get_filename('Path to RSA public cert file')
        if not size:
            size = iobject.get_int('Size (in MB) of bundled image')
        if not ssh_key:
            ssh_key = self.server.get_ssh_key_file()
        self.copy_x509(key_file, cert_file)
        if not fp:
            fp = StringIO.StringIO()
        fp.write('sudo mv %s /mnt/boto.cfg; ' % BotoConfigPath)
        fp.write('mv ~/.ssh/authorized_keys /mnt/authorized_keys; ')
        if clear_history:
            fp.write('history -c; ')
        fp.write(self.bundle_image(prefix, size, ssh_key))
        fp.write('; ')
        fp.write(self.upload_bundle(bucket, prefix, ssh_key))
        fp.write('; ')
        fp.write('sudo mv /mnt/boto.cfg %s; ' % BotoConfigPath)
        fp.write('mv /mnt/authorized_keys ~/.ssh/authorized_keys')
        command = fp.getvalue()
        print 'running the following command on the remote server:'
        print command
        t = self.ssh_client.run(command)
        print '\t%s' % t[0]
        print '\t%s' % t[1]
        print '...complete!'
        print 'registering image...'
        self.image_id = self.server.ec2.register_image(name=prefix, image_location='%s/%s.manifest.xml' % (bucket, prefix))
        return self.image_id

class CommandLineGetter(object):

    def get_ami_list(self):
        my_amis = []
        for ami in self.ec2.get_all_images():
            # hack alert, need a better way to do this!
            if ami.location.find('pyami') >= 0:
                my_amis.append((ami.location, ami))
        return my_amis
    
    def get_region(self, params):
        region = params.get('region', None)
        if isinstance(region, str) or isinstance(region, unicode):
            region = boto.ec2.get_region(region)
            params['region'] = region
        if not region:
            prop = self.cls.find_property('region_name')
            params['region'] = propget.get(prop, choices=boto.ec2.regions)
        self.ec2 = params['region'].connect()

    def get_name(self, params):
        if not params.get('name', None):
            prop = self.cls.find_property('name')
            params['name'] = propget.get(prop)

    def get_description(self, params):
        if not params.get('description', None):
            prop = self.cls.find_property('description')
            params['description'] = propget.get(prop)

    def get_instance_type(self, params):
        if not params.get('instance_type', None):
            prop = StringProperty(name='instance_type', verbose_name='Instance Type',
                                  choices=InstanceTypes)
            params['instance_type'] = propget.get(prop)

    def get_quantity(self, params):
        if not params.get('quantity', None):
            prop = IntegerProperty(name='quantity', verbose_name='Number of Instances')
            params['quantity'] = propget.get(prop)

    def get_zone(self, params):
        if not params.get('zone', None):
            prop = StringProperty(name='zone', verbose_name='EC2 Availability Zone',
                                  choices=self.ec2.get_all_zones)
            params['zone'] = propget.get(prop)
            
    def get_ami_id(self, params):
        valid = False
        while not valid:
            ami = params.get('ami', None)
            if not ami:
                prop = StringProperty(name='ami', verbose_name='AMI')
                ami = propget.get(prop)
            try:
                rs = self.ec2.get_all_images([ami])
                if len(rs) == 1:
                    valid = True
                    params['ami'] = rs[0]
            except EC2ResponseError:
                pass

    def get_group(self, params):
        group = params.get('group', None)
        if isinstance(group, str) or isinstance(group, unicode):
            group_list = self.ec2.get_all_security_groups()
            for g in group_list:
                if g.name == group:
                    group = g
                    params['group'] = g
        if not group:
            prop = StringProperty(name='group', verbose_name='EC2 Security Group',
                                  choices=self.ec2.get_all_security_groups)
            params['group'] = propget.get(prop)

    def get_key(self, params):
        keypair = params.get('keypair', None)
        if isinstance(keypair, str) or isinstance(keypair, unicode):
            key_list = self.ec2.get_all_key_pairs()
            for k in key_list:
                if k.name == keypair:
                    keypair = k.name
                    params['keypair'] = k.name
        if not keypair:
            prop = StringProperty(name='keypair', verbose_name='EC2 KeyPair',
                                  choices=self.ec2.get_all_key_pairs)
            params['keypair'] = propget.get(prop).name

    def get(self, cls, params):
        self.cls = cls
        self.get_region(params)
        self.ec2 = params['region'].connect()
        self.get_name(params)
        self.get_description(params)
        self.get_instance_type(params)
        self.get_zone(params)
        self.get_quantity(params)
        self.get_ami_id(params)
        self.get_group(params)
        self.get_key(params)

class Server(Model):

    #
    # The properties of this object consists of real properties for data that
    # is not already stored in EC2 somewhere (e.g. name, description) plus
    # calculated properties for all of the properties that are already in
    # EC2 (e.g. hostname, security groups, etc.)
    #
    name = StringProperty(unique=True, verbose_name="Name")
    description = StringProperty(verbose_name="Description")
    region_name = StringProperty(verbose_name="EC2 Region Name")
    instance_id = StringProperty(verbose_name="EC2 Instance ID")
    elastic_ip = StringProperty(verbose_name="EC2 Elastic IP Address")
    production = BooleanProperty(verbose_name="Is This Server Production", default=False)
    ami_id = CalculatedProperty(verbose_name="AMI ID", calculated_type=str, use_method=True)
    zone = CalculatedProperty(verbose_name="Availability Zone Name", calculated_type=str, use_method=True)
    hostname = CalculatedProperty(verbose_name="Public DNS Name", calculated_type=str, use_method=True)
    private_hostname = CalculatedProperty(verbose_name="Private DNS Name", calculated_type=str, use_method=True)
    groups = CalculatedProperty(verbose_name="Security Groups", calculated_type=list, use_method=True)
    security_group = CalculatedProperty(verbose_name="Primary Security Group Name", calculated_type=str, use_method=True)
    key_name = CalculatedProperty(verbose_name="Key Name", calculated_type=str, use_method=True)
    instance_type = CalculatedProperty(verbose_name="Instance Type", calculated_type=str, use_method=True)
    status = CalculatedProperty(verbose_name="Current Status", calculated_type=str, use_method=True)
    launch_time = CalculatedProperty(verbose_name="Server Launch Time", calculated_type=str, use_method=True)
    console_output = CalculatedProperty(verbose_name="Console Output", calculated_type=file, use_method=True)

    packages = []
    plugins = []

    @classmethod
    def add_credentials(cls, cfg, aws_access_key_id, aws_secret_access_key):
        if not cfg.has_section('Credentials'):
            cfg.add_section('Credentials')
        cfg.set('Credentials', 'aws_access_key_id', aws_access_key_id)
        cfg.set('Credentials', 'aws_secret_access_key', aws_secret_access_key)
        if not cfg.has_section('DB_Server'):
            cfg.add_section('DB_Server')
        cfg.set('DB_Server', 'db_type', 'SimpleDB')
        cfg.set('DB_Server', 'db_name', cls._manager.domain.name)

    @classmethod
    def create(cls, config_file=None, logical_volume = None, cfg = None, **params):
        """
        Create a new instance based on the specified configuration file or the specified
        configuration and the passed in parameters.
        
        If the config_file argument is not None, the configuration is read from there. 
        Otherwise, the cfg argument is used.
        
        The config file may include other config files with a #import reference. The included
        config files must reside in the same directory as the specified file. 
        
        The logical_volume argument, if supplied, will be used to get the current physical 
        volume ID and use that as an override of the value specified in the config file. This 
        may be useful for debugging purposes when you want to debug with a production config 
        file but a test Volume. 
        
        The dictionary argument may be used to override any EC2 configuration values in the 
        config file. 
        """
        if config_file:
            cfg = Config(path=config_file)
        if cfg.has_section('EC2'):
            # include any EC2 configuration values that aren't specified in params:
            for option in cfg.options('EC2'):
                if option not in params:
                    params[option] = cfg.get('EC2', option)
        getter = CommandLineGetter()
        getter.get(cls, params)
        region = params.get('region')
        ec2 = region.connect()
        cls.add_credentials(cfg, ec2.aws_access_key_id, ec2.aws_secret_access_key)
        ami = params.get('ami')
        kp = params.get('keypair')
        group = params.get('group')
        zone = params.get('zone')
        # deal with possibly passed in logical volume:
        if logical_volume != None:
           cfg.set('EBS', 'logical_volume_name', logical_volume.name) 
        cfg_fp = StringIO.StringIO()
        cfg.write(cfg_fp)
        # deal with the possibility that zone and/or keypair are strings read from the config file:
        if isinstance(zone, Zone):
            zone = zone.name
        if isinstance(kp, KeyPair):
            kp = kp.name
        reservation = ami.run(min_count=1,
                              max_count=params.get('quantity', 1),
                              key_name=kp,
                              security_groups=[group],
                              instance_type=params.get('instance_type'),
                              placement = zone,
                              user_data = cfg_fp.getvalue())
        l = []
        i = 0
        elastic_ip = params.get('elastic_ip')
        instances = reservation.instances
        if elastic_ip != None and instances.__len__() > 0:
            instance = instances[0]
            print 'Waiting for instance to start so we can set its elastic IP address...'
            # Sometimes we get a message from ec2 that says that the instance does not exist.
            # Hopefully the following delay will giv eec2 enough time to get to a stable state:
            time.sleep(5) 
            while instance.update() != 'running':
                time.sleep(1)
            instance.use_ip(elastic_ip)
            print 'set the elastic IP of the first instance to %s' % elastic_ip
        for instance in instances:
            s = cls()
            s.ec2 = ec2
            s.name = params.get('name') + '' if i==0 else str(i)
            s.description = params.get('description')
            s.region_name = region.name
            s.instance_id = instance.id
            if elastic_ip and i == 0:
                s.elastic_ip = elastic_ip
            s.put()
            l.append(s)
            i += 1
        return l
    
    @classmethod
    def create_from_instance_id(cls, instance_id, name, description=''):
        regions = boto.ec2.regions()
        for region in regions:
            ec2 = region.connect()
            try:
                rs = ec2.get_all_instances([instance_id])
            except:
                rs = []
            if len(rs) == 1:
                s = cls()
                s.ec2 = ec2
                s.name = name
                s.description = description
                s.region_name = region.name
                s.instance_id = instance_id
                s._reservation = rs[0]
                for instance in s._reservation.instances:
                    if instance.id == instance_id:
                        s._instance = instance
                s.put()
                return s
        return None

    @classmethod
    def create_from_current_instances(cls):
        servers = []
        regions = boto.ec2.regions()
        for region in regions:
            ec2 = region.connect()
            rs = ec2.get_all_instances()
            for reservation in rs:
                for instance in reservation.instances:
                    try:
                        Server.find(instance_id=instance.id).next()
                        boto.log.info('Server for %s already exists' % instance.id)
                    except StopIteration:
                        s = cls()
                        s.ec2 = ec2
                        s.name = instance.id
                        s.region_name = region.name
                        s.instance_id = instance.id
                        s._reservation = reservation
                        s.put()
                        servers.append(s)
        return servers
    
    def __init__(self, id=None, **kw):
        Model.__init__(self, id, **kw)
        self.ssh_key_file = None
        self.ec2 = None
        self._cmdshell = None
        self._reservation = None
        self._instance = None
        self._setup_ec2()

    def _setup_ec2(self):
        if self.ec2 and self._instance and self._reservation:
            return
        if self.id:
            if self.region_name:
                for region in boto.ec2.regions():
                    if region.name == self.region_name:
                        self.ec2 = region.connect()
                        if self.instance_id and not self._instance:
                            try:
                                rs = self.ec2.get_all_instances([self.instance_id])
                                if len(rs) >= 1:
                                    for instance in rs[0].instances:
                                        if instance.id == self.instance_id:
                                            self._reservation = rs[0]
                                            self._instance = instance
                            except EC2ResponseError:
                                pass
                            
    def _status(self):
        status = ''
        if self._instance:
            self._instance.update()
            status = self._instance.state
        return status

    def _hostname(self):
        hostname = ''
        if self._instance:
            hostname = self._instance.public_dns_name
        return hostname

    def _private_hostname(self):
        hostname = ''
        if self._instance:
            hostname = self._instance.private_dns_name
        return hostname

    def _instance_type(self):
        it = ''
        if self._instance:
            it = self._instance.instance_type
        return it

    def _launch_time(self):
        lt = ''
        if self._instance:
            lt = self._instance.launch_time
        return lt

    def _console_output(self):
        co = ''
        if self._instance:
            co = self._instance.get_console_output()
        return co

    def _groups(self):
        gn = []
        if self._reservation:
            gn = self._reservation.groups
        return gn

    def _security_group(self):
        groups = self._groups()
        if len(groups) >= 1:
            return groups[0].id
        return ""

    def _zone(self):
        zone = None
        if self._instance:
            zone = self._instance.placement
        return zone

    def _key_name(self):
        kn = None
        if self._instance:
            kn = self._instance.key_name
        return kn

    def put(self):
        Model.put(self)
        self._setup_ec2()

    def delete(self):
        if self.production:
            raise ValueError("Can't delete a production server")
        #self.stop()
        Model.delete(self)

    def stop(self):
        if self.production:
            raise ValueError("Can't delete a production server")
        if self._instance:
            self._instance.stop()

    def terminate(self):
        if self.production:
            raise ValueError("Can't delete a production server")
        if self._instance:
            self._instance.terminate()

    def reboot(self):
        if self._instance:
            self._instance.reboot()

    def wait(self):
        while self.status != 'running':
            time.sleep(5)

    def get_ssh_key_file(self):
        if not self.ssh_key_file:
            ssh_dir = os.path.expanduser('~/.ssh')
            if os.path.isdir(ssh_dir):
                ssh_file = os.path.join(ssh_dir, '%s.pem' % self.key_name)
                if os.path.isfile(ssh_file):
                    self.ssh_key_file = ssh_file
            if not self.ssh_key_file:
                iobject = IObject()
                self.ssh_key_file = iobject.get_filename('Path to OpenSSH Key file')
        return self.ssh_key_file

    def get_cmdshell(self):
        if not self._cmdshell:
            import cmdshell
            self.get_ssh_key_file()
            self._cmdshell = cmdshell.start(self)
        return self._cmdshell

    def reset_cmdshell(self):
        self._cmdshell = None

    def run(self, command):
        with closing(self.get_cmdshell()) as cmd:
            status = cmd.run(command)
        return status

    def get_bundler(self, uname='root'):
        self.get_ssh_key_file()
        return Bundler(self, uname)

    def get_ssh_client(self, uname='root', ssh_pwd=None):
        from boto.manage.cmdshell import SSHClient
        self.get_ssh_key_file()
        return SSHClient(self, uname=uname, ssh_pwd=ssh_pwd)

    def install(self, pkg):
        return self.run('apt-get -y install %s' % pkg)


    
