Пример #1
0
from dopy.manager import DoManager
import os

API_VERSION = 2
SIZE = '512mb'
REGION = 'nyc2'
PURPOSE = 'wordpress'
VERSION = '1'
IMAGE = 'ubuntu-14-04-x64'
USER_DATA = '''#cloud-config
users:
    - name: ansible
      ssh-authorized-keys:
        - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOd/iTQUd6Hb/KTpDjjPJotOWHfTH71U5L7x9Y4y9bo7Zvtp/m1WZyR55Ut6uBfGHscD5WRNv6VFsRIHRRjiHP+pGkB4piSUNuOduEOL/FCzmytQLmg7mYZZRGHLYXIoFJV/kdXmjexXSySxJSSp5X5EcH/pLWcKhRK9HiX4IGOBZfNwxaL/VODxU989jNXuKPnF6XfuNVf9p7JYkc4zaDy4752pPCWU2oTfq6y5Ll0vqoSpb62gCUf94CYU5eQddIeZEutTi2UiuqbsA7sEvsZpp/iXXvkaCAWMNRY6VMy5AUavDpNk4tZ/ITcieCWYdfDPCBDcfXwgANlVorHGaR gdunn@san
      sudo: ['ALL=(ALL) NOPASSWD:ALL']
      groups: sudo
      shell: /bin/bash
runcmd:
  - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
  - sed -i -e '$aAllowUsers ansible' /etc/ssh/sshd_config
  - restart ssh
'''


do = DoManager(None, os.environ['DO_API_TOKEN'], API_VERSION)

results = do.new_droplet('{0}-{1}-{2}'.format(REGION, PURPOSE, VERSION), SIZE, IMAGE, REGION, user_data=USER_DATA)

for i in results.keys():
    print('{0}: {1}'.format(i, results[i]))
Пример #2
0
class DigitalOceanProvider(FactoryProvider):
    NAME = 'digital-ocean'

    DEFAULT_IMAGE_SLUG = "ubuntu-14-04-x64"  # Ubuntu latest LTS 64bit
    DEFAULT_SIZE_SLUG = "1gb"
    DEFAULT_REGION_SLUG = "ams3"

    def __init__(self):
        super(DigitalOceanProvider, self).__init__(self.NAME, DOGeneral, DOExt)
        if (not self.env.initialized) or (not self.env.general) or (not self.env.general.api_token):
            g = self._input_general_env_conf()
        else:
            g = self.env.general
        self.manager = DoManager(None, g.api_token, api_version=2)

    def _input_general_env_conf(self):
        print ('\nThe DigitalOcean API (v2) token is not configured.')
        print ('If you don\'t have it please visit ' \
              'https://cloud.digitalocean.com/settings/applications and generate one.')
        api_token = io.input_value('api token')
        do_general = DOGeneral(api_token)
        self.env.set_general(do_general)
        return do_general

    def define_box(self):
        ip = None
        ext = DOExt()

        if io.input_yes_no('register an existing droplet'):
            droplet_id = io.input_value('droplet id')
            droplet_info = self.manager.show_droplet(droplet_id)
            ext.id = droplet_id
            name = droplet_info['name']
            created = droplet_info['created_at']
            print ('\nFound droplet \'{0}\' (created {1})'.format(name, created))
            ip = io.xstr(droplet_info['ip_address'])
            print ('IP: %s' % ip)
            ext.image = droplet_info['image']['id']
            print ('Image: %s' % ext.image)
            ext.size = droplet_info['size']['slug']
            print ('Size: %s' % ext.size)
            ext.region = droplet_info['region']['slug']
            print ('Region: %s\n' % ext.region)

            playbook = io.input_path('playbook path')
            hostname = self.fetch_box_hosts(playbook)
            user = io.input_value('remote user', self.active_user)
        else:
            playbook = io.input_path('playbook path')
            hostname = self.fetch_box_hosts(playbook)
            name = io.input_value('box name', self.suggest_name(hostname))
            user = io.input_value('remote user', self.active_user)

            all_images = self.manager.all_images()
            print ('\nAvailable images: \n%s' % self._print_object_id_name(all_images))
            default_image = next((img for img in all_images
                                  if img['slug'] and self.DEFAULT_IMAGE_SLUG in img['slug']), None)
            if default_image:
                image_desc = '{0} - {1} {2}'.format(
                    default_image['id'],
                    default_image['distribution'],
                    default_image['name']
                )
                ext.image = io.input_value('image', default_image['id'], image_desc)
            else:
                ext.image = io.input_value('image')

            all_sizes = self.manager.sizes()
            sizes_slug = [o['slug'] for o in all_sizes]
            print ('\nAvailable sizes: \n%s' % '\n'.join(sizes_slug))
            ext.size = io.input_choice('size', self.DEFAULT_SIZE_SLUG, choices=sizes_slug)

            all_regions = self.manager.all_regions()
            regions_slug = [o['slug'] for o in all_regions]
            print ('\nAvailable regions: \n%s' % '\n'.join(regions_slug))
            ext.region = io.input_choice('region', self.DEFAULT_REGION_SLUG, choices=regions_slug)

            ext.keys = self._input_ssh_keys()

        return Box(name, playbook, hostname, ip, user, extra=ext)

    @staticmethod
    def _print_object_id_name(objs):
        def _dist_if_exists(prop):
            return prop['distribution'] + ' ' if 'distribution' in prop else ''

        return '\n'.join([str(o['id']) + ' -> ' + _dist_if_exists(o) + o['name'] for o in objs])

    def redefine_box(self, previous_box):
        playbook = io.input_path('playbook path', previous_box.playbook)
        hostname = self.fetch_box_hosts(playbook)
        ip = previous_box.ip
        user = io.input_value('remote user', previous_box.remote_user)

        if not previous_box.extra.id:
            ext = DOExt()
            ext.id = previous_box.extra.id
            all_images = self.manager.all_images()
            print ('\nAvailable images: \n%s' % self._print_object_id_name(all_images))
            prev_image = next((img for img in all_images
                               if previous_box.extra.image == img['id']), None)
            if prev_image:
                prev_image_desc = '{0} - {1} {2}'.format(
                    prev_image['id'],
                    prev_image['distribution'],
                    prev_image['name']
                )
                ext.image = io.input_value('image', prev_image['id'], prev_image_desc)
            else:
                ext.image = io.input_value('image')

            all_sizes = self.manager.sizes()
            sizes_slug = [o['slug'] for o in all_sizes]
            print ('\nAvailable sizes: \n%s' % '\n'.join(sizes_slug))
            ext.size = io.input_value('size', previous_box.extra.size)

            all_regions = self.manager.all_regions()
            regions_slug = [o['slug'] for o in all_regions]
            print ('\nAvailable regions: \n%s' % '\n'.join(regions_slug))
            ext.region = io.input_value('region', previous_box.extra.region)

            ext.keys = self._input_ssh_keys(previous_box.extra.keys)
        else:
            ext = previous_box.extra

        return Box(previous_box.name, playbook, hostname, ip, user, extra=ext)

    def add_box(self, box):
        if not box.ip:
            self.create(box)
        SimpleProvider.add_box(self, box)

    def create(self, box):
        ext = box.extra
        if not ext.id:
            if not ext.keys:
                print ('\nNo valid keys are defined.')
                print ('Please run `reconfigure {0}` to provide them.'.format(box.name))
                return False
            print ('\nCreating instance \'{0}\' ...'.format(box.name))
            droplet = self.manager.new_droplet(
                name=box.name, size_id=ext.size,
                image_id=ext.image, region_id=ext.region,
                ssh_key_ids=ext.keys.split(',')
            )
            box.extra.id = droplet['id']
            box.ip = self._wait_to_be_active(box.extra.id)
        else:
            info = self.manager.show_droplet(ext.id)
            print ('Droplet {0} already exists - status: {1}.'.format(ext.id, info['status']))
        create_user(box, self.loader)

    def start(self, box):
        box_id = box.extra.id
        print ('Starting droplet %s ...' % box_id)
        self.manager.power_on_droplet(box_id)
        self._wait_to_be_active(box_id)

    def stop(self, box):
        box_id = box.extra.id
        print ('Stopping droplet %s ...' % box_id)
        self.manager.power_off_droplet(box_id)

    def destroy(self, box):
        if io.input_yes_no('destroy the droplet \'{0}\''.format(box.name)):
            box_id = box.extra.id
            box.ip = None
            box.extra.id = None
            print ('Destroying droplet %s ...' % box_id)
            self.manager.destroy_droplet(box_id, scrub_data=True)

    def rebuild(self, box):
        ext = box.extra
        print ('Rebuilding droplet %s ...' % ext.id)
        self.manager.rebuild_droplet(ext.id, ext.image)
        self._wait_to_be_active(ext.id)
        create_user(box, self.loader)

    def status(self, box):
        print (self.manager.show_droplet(box.extra.id)['status'])

    def _wait_to_be_active(self, droplet_id, wait_timeout=300):
        end_time = time.time() + wait_timeout
        while time.time() < end_time:
            print ('Waiting for droplet %s to be active ...' % droplet_id)
            time.sleep(min(20, end_time - time.time()))

            droplet = self.manager.show_droplet(droplet_id)
            if droplet['status'] == 'active':
                droplet_ip_address = droplet['ip_address']
                if not droplet_ip_address:
                    raise DoError('No ip is found.', droplet_id)
                print ('\nDroplet %s is now active with ip %s\n' % (droplet_id, droplet_ip_address))
                time.sleep(10)  # Wait for some network latency ...
                return droplet_ip_address
        raise DoError('Wait for droplet running timeout', droplet_id)

    def _input_ssh_keys(self, previous=None):
        all_keys = self.manager.all_ssh_keys()
        print ('\nAvailable keys: \n%s' % self._print_object_id_name(all_keys))
        if not previous:
            default_keys = ','.join([str(k['id']) for k in all_keys])
        else:
            default_keys = previous
        return io.input_value('keys', default_keys)