def update_image(digitalocean_account, droplet_id, droplet_name):
    try:
        do_api = DigitalOceanAPI(digitalocean_account.client_id, digitalocean_account.api_key)
        
        result = take_snapshot(do_api, droplet_id, {'name': droplet_name})
        if 'OK' in result['status']:
            images = do_api.get_all_images()
            new_image = [i for i in images if droplet_name in i['name']][0]
            
            regions = do_api.get_all_regions()
            results = []
            for r in regions:
                results.append(do_api.image_transfer(new_image['id'], {'region_id': r['id']}))
            #wait a while for the image to be transferred across regions
            success_ids = [r['event_id'] for r in results if 'OK' in r['status']]
            for id in success_ids:
                if not wait_on_event_completion(do_api, id, interval=120):
                    raise Exception('Could not update image')
            
            images = do_api.get_all_images()
            image = [i for i in images if droplet_name in i['name']][0]
            if image['regions'] == [r['id'] for r in regions]:
                print 'Image creation and transfer complete. Remove the outdated image'
                return image
            else:
                print 'Image was not transferred successfully'
                raise
    except Exception as e:
        print '%s' % (e)
def update_image(digitalocean_account, droplet_id, droplet_name):
    try:
        do_api = DigitalOceanAPI(digitalocean_account.client_id,
                                 digitalocean_account.api_key)

        result = take_snapshot(do_api, droplet_id, {'name': droplet_name})
        if 'OK' in result['status']:
            images = do_api.get_all_images()
            new_image = [i for i in images if droplet_name in i['name']][0]

            regions = do_api.get_all_regions()
            results = []
            for r in regions:
                results.append(
                    do_api.image_transfer(new_image['id'],
                                          {'region_id': r['id']}))
            #wait a while for the image to be transferred across regions
            success_ids = [
                r['event_id'] for r in results if 'OK' in r['status']
            ]
            for id in success_ids:
                if not wait_on_event_completion(do_api, id, interval=120):
                    raise Exception('Could not update image')

            images = do_api.get_all_images()
            image = [i for i in images if droplet_name in i['name']][0]
            if image['regions'] == [r['id'] for r in regions]:
                print 'Image creation and transfer complete. Remove the outdated image'
                return image
            else:
                print 'Image was not transferred successfully'
                raise
    except Exception as e:
        print '%s' % (e)
def launch_new_server(digitalocean_account, _):
    
    image = {}
    droplet = None
    try:
        new_root_password = psi_utils.generate_password()
        new_stats_password = psi_utils.generate_password()
        do_api = DigitalOceanAPI(digitalocean_account.client_id, digitalocean_account.api_key)
        
        image['image_id'] = digitalocean_account.base_id
        
        regions = do_api.get_all_regions()
        image['region_id'] = random.choice([region['id'] for region in regions if region['id'] in [1,2,3,4,5,6,7]])

        for r in regions:
            if image['region_id'] == r['id']:
                print 'Using region: %s' % (r['name'])
                break

        image['size_id'] = digitalocean_account.base_size_id

        # get a list of image sizes and see if the size is available (maybe some checks)
        droplet_sizes = do_api.get_all_droplet_sizes()
        if image['size_id'] not in [size['id'] for size in droplet_sizes]:
            raise Exception('Droplet size not available')
                    
        # Hostname generator
        image['name'] = generate_random_string(prefix=('do-' + str(image['region_id']) + str(image['size_id']) + '-'))
        image['ssh_key_ids'] = digitalocean_account.ssh_key_template_id

        print 'Launching %s, using image %s' % (image['name'], str(image['image_id']))
        resp = do_api.create_new_droplet(image)

        if resp['status'] != 'OK':
            raise Exception(resp['message'] + ': ' + resp['error_message'])
        
        droplet = resp['droplet']
        if not wait_on_event_completion(do_api, resp['droplet']['event_id'], interval=30):
            raise Exception('Event did not complete in time')
        
        print 'Waiting for the droplet to power on and get an IP address'
        time.sleep(30)

        # get more details about droplet
        resp = do_api.droplet_show(resp['droplet']['id'])
        droplet = resp['droplet']
        if resp['status'] != 'OK':
            raise Exception(resp['message'] + ': ' + resp['error_message'])

        if droplet['status'] != 'active':
            start_droplet(do_api, droplet['id'])

        provider_id = str(droplet['id'])
        region = get_datacenter_region(droplet['region_id'])
        datacenter_name = 'Digital Ocean ' + next((r for r in regions if r['id'] == droplet['region_id']), None)['name']

        new_host_public_key = refresh_credentials(digitalocean_account, droplet['ip_address'], 
                                                  new_root_password, new_stats_password)
        assert(new_host_public_key)

    except Exception as e:
        print type(e), str(e)
        if droplet != None:
            if 'id' in droplet:
                remove_droplet(do_api, droplet['id'])
            else:
                print type(e), "No droplet to be deleted: ", str(droplet)
        raise

    
    return (image['name'], None, provider_id, droplet['ip_address'],
            digitalocean_account.base_ssh_port, 'root', 
            new_root_password, ' '.join(new_host_public_key.split(' ')[:2]),
            digitalocean_account.base_stats_username, new_stats_password, 
            datacenter_name, region, None, None, None, None)
def remove_server(digitalocean_account, droplet_id):
    do_api = DigitalOceanAPI(digitalocean_account.client_id,
                             digitalocean_account.api_key)
    remove_droplet(do_api, droplet_id)
def launch_new_server(digitalocean_account, is_TCS, _):

    # TODO-TCS: select base image based on is_TCS flag

    image = {}
    droplet = None
    try:
        new_root_password = psi_utils.generate_password()
        new_stats_password = psi_utils.generate_password()
        do_api = DigitalOceanAPI(digitalocean_account.client_id,
                                 digitalocean_account.api_key)

        image['image_id'] = digitalocean_account.base_id

        regions = do_api.get_all_regions()
        image['region_id'] = random.choice([
            region['id'] for region in regions
            if region['id'] in [1, 2, 3, 4, 5, 6, 7]
        ])

        for r in regions:
            if image['region_id'] == r['id']:
                print 'Using region: %s' % (r['name'])
                break

        image['size_id'] = digitalocean_account.base_size_id

        # get a list of image sizes and see if the size is available (maybe some checks)
        droplet_sizes = do_api.get_all_droplet_sizes()
        if image['size_id'] not in [size['id'] for size in droplet_sizes]:
            raise Exception('Droplet size not available')

        # Hostname generator
        image['name'] = generate_random_string(
            prefix=('do-' + str(image['region_id']) + str(image['size_id']) +
                    '-'))
        image['ssh_key_ids'] = digitalocean_account.ssh_key_template_id

        print 'Launching %s, using image %s' % (image['name'],
                                                str(image['image_id']))
        resp = do_api.create_new_droplet(image)

        if resp['status'] != 'OK':
            raise Exception(resp['message'] + ': ' + resp['error_message'])

        droplet = resp['droplet']
        if not wait_on_event_completion(
                do_api, resp['droplet']['event_id'], interval=30):
            raise Exception('Event did not complete in time')

        print 'Waiting for the droplet to power on and get an IP address'
        time.sleep(30)

        # get more details about droplet
        resp = do_api.droplet_show(resp['droplet']['id'])
        droplet = resp['droplet']
        if resp['status'] != 'OK':
            raise Exception(resp['message'] + ': ' + resp['error_message'])

        if droplet['status'] != 'active':
            start_droplet(do_api, droplet['id'])

        provider_id = str(droplet['id'])
        region = get_datacenter_region(droplet['region_id'])
        datacenter_name = 'Digital Ocean ' + next(
            (r for r in regions if r['id'] == droplet['region_id']),
            None)['name']

        new_host_public_key = refresh_credentials(digitalocean_account,
                                                  droplet['ip_address'],
                                                  new_root_password,
                                                  new_stats_password)
        assert (new_host_public_key)

    except Exception as e:
        print type(e), str(e)
        if droplet != None:
            if 'id' in droplet:
                remove_droplet(do_api, droplet['id'])
            else:
                print type(e), "No droplet to be deleted: ", str(droplet)
        raise

    return (image['name'], is_TCS, None, provider_id, droplet['ip_address'],
            digitalocean_account.base_ssh_port, 'root', new_root_password,
            ' '.join(new_host_public_key.split(' ')[:2]),
            digitalocean_account.base_stats_username, new_stats_password,
            datacenter_name, region, None, None, None, None)