Ejemplo n.º 1
0
 def execute(self, args):
     cci = CCIManager(self.client)
     cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')
     if args['--really'] or no_going_back(cci_id):
         cci.cancel_instance(cci_id)
     else:
         CLIAbort('Aborted')
Ejemplo n.º 2
0
    def on_get(self, req, resp, tenant_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        params = get_list_params(req)

        sl_instances = cci.list_instances(**params)
        if not isinstance(sl_instances, list):
            sl_instances = [sl_instances]

        results = []
        for instance in sl_instances:
            results.append({
                'id': instance['id'],
                'links': [
                    {
                        'href': self.app.get_endpoint_url(
                            'compute', req, 'v2_server', server_id=id),
                        'rel': 'self',
                    }
                ],
                'name': instance['hostname'],
            })

        resp.status = 200
        resp.body = {'servers': results}
Ejemplo n.º 3
0
    def execute(self, args):
        data = {}

        if args['--userdata'] and args['--userfile']:
            raise ArgumentError('[-u | --userdata] not allowed with '
                                '[-F | --userfile]')
        if args['--userfile']:
            if not os.path.exists(args['--userfile']):
                raise ArgumentError(
                    'File does not exist [-u | --userfile] = %s'
                    % args['--userfile'])

        if args.get('--userdata'):
            data['userdata'] = args['--userdata']
        elif args.get('--userfile'):
            with open(args['--userfile'], 'r') as userfile:
                data['userdata'] = userfile.read()

        data['hostname'] = args.get('--hostname')
        data['domain'] = args.get('--domain')

        cci = CCIManager(self.client)
        cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')
        if not cci.edit(cci_id, **data):
            raise CLIAbort("Failed to update CCI")
Ejemplo n.º 4
0
    def on_get(self, req, resp, tenant_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        params = get_list_params(req)

        sl_instances = cci.list_instances(**params)
        if not isinstance(sl_instances, list):
            sl_instances = [sl_instances]

        results = []
        for instance in sl_instances:
            results.append({
                'id':
                instance['id'],
                'links': [{
                    'href':
                    self.app.get_endpoint_url('compute',
                                              req,
                                              'v2_server',
                                              server_id=id),
                    'rel':
                    'self',
                }],
                'name':
                instance['hostname'],
            })

        resp.status = 200
        resp.body = {'servers': results}
Ejemplo n.º 5
0
    def execute(self, args):
        cci = CCIManager(self.client)

        cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')

        if args['--all']:
            additional_disks = True
        else:
            additional_disks = False

        capture = cci.capture(cci_id,
                              args.get('--name'),
                              additional_disks,
                              args.get('--note'))

        table = KeyValueTable(['Name', 'Value'])
        table.align['Name'] = 'r'
        table.align['Value'] = 'l'

        table.add_row(['cci_id', capture['guestId']])
        table.add_row(['date', capture['createDate'][:10]])
        table.add_row(['time', capture['createDate'][11:19]])
        table.add_row(['transaction', transaction_status(capture)])
        table.add_row(['transaction_id', capture['id']])
        table.add_row(['all_disks', additional_disks])
        return table
Ejemplo n.º 6
0
    def execute(self, args):
        public = args['public']

        cci = CCIManager(self.client)
        cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')

        cci.change_port_speed(cci_id, public, args['--speed'])
Ejemplo n.º 7
0
class SoftLayer(object):
    def __init__(self, config, client=None):
        self.config = config
        if client is None:
            client = Client(auth=self.config['auth'],
                            endpoint_url=self.config['endpoint_url'])
        self.client = client
        self.ssh = SshKeyManager(client)
        self.instances = CCIManager(client)

    @classmethod
    def get_config(cls):
        provider_conf = client_conf.get_client_settings()
        if 'SL_SSH_KEY' in os.environ:
            provider_conf['ssh_key'] = os.environ['SL_SSH_KEY']
        if not ('auth' in provider_conf and 'endpoint_url' in provider_conf):
            raise ConfigError("Missing digital ocean api credentials")
        return provider_conf

    def get_ssh_keys(self):
        keys = map(SSHKey, self.ssh.list_keys())
        if 'ssh_key' in self.config:
            keys = [k for k in keys if k.name == self.config['ssh_key']]
        log.debug("Using SoftLayer ssh keys: %s" % ", ".join(k.name
                                                             for k in keys))
        return keys

    def get_instances(self):
        return map(Instance, self.instances.list_instances())

    def get_instance(self, instance_id):
        return Instance(self.instances.get_instance(instance_id))

    def launch_instance(self, params):
        return Instance(self.instances.create_instance(**params))

    def terminate_instance(self, instance_id):
        self.instances.cancel_instance(instance_id)

    def wait_on(self, instance):
        # Wait up to 5 minutes, in 30 sec increments
        result = self._wait_on_instance(instance, 30, 10)
        if not result:
            raise ProviderError("Could not provision instance before timeout")
        return result

    def _wait_on_instance(self, instance, limit, delay=10):
        # Redo cci.wait to give user feedback in verbose mode.
        for count, new_instance in enumerate(itertools.repeat(instance.id)):
            instance = self.get_instance(new_instance)
            if not instance.get('activeTransaction', {}).get('id') and \
               instance.get('provisionDate'):
                return True
            if count >= limit:
                return False
            if count and count % 3 == 0:
                log.debug("Waiting for instance:%s ip:%s waited:%ds" %
                          (instance.name, instance.ip_address, count * delay))
            time.sleep(delay)
Ejemplo n.º 8
0
 def __init__(self, config, client=None):
     self.config = config
     if client is None:
         client = Client(auth=self.config['auth'],
                         endpoint_url=self.config['endpoint_url'])
     self.client = client
     self.ssh = SshKeyManager(client)
     self.instances = CCIManager(client)
Ejemplo n.º 9
0
    def on_get(self, req, resp, tenant_id, server_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        instance = cci.get_instance(server_id, mask=get_virtual_guest_mask())

        results = get_server_details_dict(self.app, req, instance)

        resp.body = {'server': results}
Ejemplo n.º 10
0
def global_search(search):
    client = get_client()
    match_string = '<span class="text-primary">%s</span>' % search

    term = re.compile(search, re.IGNORECASE)

    results = []

    if 'vm' in app.config['installed_blueprints']:
        cci = CCIManager(client)
        #        if hostname_regex.match(term):
        for vm in cci.list_instances():
            if term.match(vm['hostname']) or \
               term.match(vm.get('primaryIpAddress', '')):
                text = '%s (%s)' % (vm['fullyQualifiedDomainName'],
                                    vm.get('primaryIpAddress', 'No Public IP'))
                text = term.sub(match_string, text)

                results.append({
                    'label':
                    '<strong>VM:</strong> ' + text,
                    'value':
                    url_for('vm_module.view', vm_id=vm['id'])
                })
    if 'servers' in app.config['installed_blueprints']:
        hw = HardwareManager(client)

        for svr in hw.list_hardware():
            if term.match(svr['hostname']) or \
               term.match(svr.get('primaryIpAddress', '')):
                text = '%s (%s)' % (svr['fullyQualifiedDomainName'],
                                    svr.get('primaryIpAddress',
                                            'No Public IP'))
                text = term.sub(match_string, text)

                results.append({
                    'label':
                    '<strong>Server:</strong> ' + text,
                    'value':
                    url_for('server_module.view', server_id=svr['id'])
                })
    if 'sshkeys' in app.config['installed_blueprints']:
        ssh = SshKeyManager(client)

        for key in ssh.list_keys():
            if term.match(key['label']) or term.match(key['fingerprint']):
                text = '%s (%s)' % (key['label'], key['fingerprint'])
                text = term.sub(match_string, text)

                results.append({
                    'label':
                    '<strong>SSH Key:</strong> ' + text,
                    'value':
                    url_for('ssh_module.view', key_id=key['id'])
                })

    return results
Ejemplo n.º 11
0
    def on_get(self, req, resp, tenant_id, server_id):
        client = req.env["sl_client"]
        cci = CCIManager(client)

        instance = cci.get_instance(server_id, mask=get_virtual_guest_mask())

        results = get_server_details_dict(self.app, req, instance)

        resp.body = {"server": results}
Ejemplo n.º 12
0
    def execute(self, args):
        cci = CCIManager(self.client)

        cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')
        ready = cci.wait_for_ready(cci_id, int(args.get('--wait') or 0))

        if ready:
            return "READY"
        else:
            raise CLIAbort("Instance %s not ready" % cci_id)
Ejemplo n.º 13
0
 def execute(self, args):
     cci = CCIManager(self.client)
     cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')
     keys = []
     if args.get('--key'):
         for key in args.get('--key'):
             key_id = resolve_id(SshKeyManager(self.client).resolve_ids,
                                 key, 'SshKey')
             keys.append(key_id)
     if args['--really'] or no_going_back(cci_id):
         cci.reload_instance(cci_id, args['--postinstall'], keys)
     else:
         CLIAbort('Aborted')
Ejemplo n.º 14
0
    def on_delete(self, req, resp, tenant_id, server_id):
        client = req.env["sl_client"]
        cci = CCIManager(client)

        try:
            cci.cancel_instance(server_id)
        except SoftLayerAPIError as e:
            if "active transaction" in e.faultString:
                return bad_request(
                    resp, message="Can not cancel an instance when there is already" " an active transaction", code=409
                )
            raise
        resp.status = 204
Ejemplo n.º 15
0
    def _update_with_like_args(self, args):
        """ Update arguments with options taken from a currently running CCI.

        :param CCIManager args: A CCIManager
        :param dict args: CLI arguments
        """
        if args['--like']:
            cci = CCIManager(self.client)
            cci_id = resolve_id(cci.resolve_ids, args.pop('--like'), 'CCI')
            like_details = cci.get_instance(cci_id)
            like_args = {
                '--hostname': like_details['hostname'],
                '--domain': like_details['domain'],
                '--cpu': like_details['maxCpu'],
                '--memory': like_details['maxMemory'],
                '--hourly': like_details['hourlyBillingFlag'],
                '--monthly': not like_details['hourlyBillingFlag'],
                '--datacenter': like_details['datacenter']['name'],
                '--network': like_details['networkComponents'][0]['maxSpeed'],
                '--user-data': like_details['userData'] or None,
                '--postinstall': like_details.get('postInstallScriptUri'),
                '--dedicated': like_details['dedicatedAccountHostOnlyFlag'],
                '--private': like_details['privateNetworkOnlyFlag'],
            }

            # Handle mutually exclusive options
            like_image = lookup(like_details,
                                'blockDeviceTemplateGroup',
                                'globalIdentifier')
            like_os = lookup(like_details,
                             'operatingSystem',
                             'softwareLicense',
                             'softwareDescription',
                             'referenceCode')
            if like_image and not args.get('--os'):
                like_args['--image'] = like_image
            elif like_os and not args.get('--image'):
                like_args['--os'] = like_os

            if args.get('--hourly'):
                like_args['--monthly'] = False

            if args.get('--monthly'):
                like_args['--hourly'] = False

            # Merge like CCI options with the options passed in
            for key, value in like_args.items():
                if args.get(key) in [None, False]:
                    args[key] = value
Ejemplo n.º 16
0
    def on_put(self, req, resp, tenant_id, server_id):
        client = req.env["sl_client"]
        cci = CCIManager(client)
        body = json.loads(req.stream.read().decode())

        if "name" in lookup(body, "server"):
            if lookup(body, "server", "name").strip() == "":
                return bad_request(resp, message="Server name is blank")

            cci.edit(server_id, hostname=lookup(body, "server", "name"))

        instance = cci.get_instance(server_id, mask=get_virtual_guest_mask())

        results = get_server_details_dict(self.app, req, instance)
        resp.body = {"server": results}
Ejemplo n.º 17
0
    def on_put(self, req, resp, tenant_id, server_id):
        client = req.env['sl_client']
        cci = CCIManager(client)
        body = json.loads(req.stream.read().decode())

        if 'name' in lookup(body, 'server'):
            if lookup(body, 'server', 'name').strip() == '':
                return bad_request(resp, message='Server name is blank')

            cci.edit(server_id, hostname=lookup(body, 'server', 'name'))

        instance = cci.get_instance(server_id, mask=get_virtual_guest_mask())

        results = get_server_details_dict(self.app, req, instance)
        resp.body = {'server': results}
Ejemplo n.º 18
0
    def on_delete(self, req, resp, tenant_id, server_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        try:
            cci.cancel_instance(server_id)
        except SoftLayerAPIError as e:
            if 'active transaction' in e.faultString:
                return bad_request(
                    resp,
                    message='Can not cancel an instance when there is already'
                    ' an active transaction',
                    code=409)
            raise
        resp.status = 204
Ejemplo n.º 19
0
def global_search(search):
    client = get_client()
    match_string = '<span class="text-primary">%s</span>' % search

    term = re.compile(search, re.IGNORECASE)

    results = []

    if 'vm' in app.config['installed_blueprints']:
        cci = CCIManager(client)
#        if hostname_regex.match(term):
        for vm in cci.list_instances():
            if term.match(vm['hostname']) or \
               term.match(vm.get('primaryIpAddress', '')):
                text = '%s (%s)' % (vm['fullyQualifiedDomainName'],
                                    vm.get('primaryIpAddress', 'No Public IP'))
                text = term.sub(match_string, text)

                results.append({'label': '<strong>VM:</strong> ' + text,
                                'value': url_for('vm_module.view',
                                                 vm_id=vm['id'])})
    if 'servers' in app.config['installed_blueprints']:
        hw = HardwareManager(client)

        for svr in hw.list_hardware():
            if term.match(svr['hostname']) or \
               term.match(svr.get('primaryIpAddress', '')):
                text = '%s (%s)' % (svr['fullyQualifiedDomainName'],
                                    svr.get('primaryIpAddress',
                                            'No Public IP'))
                text = term.sub(match_string, text)

                results.append({'label': '<strong>Server:</strong> ' + text,
                                'value': url_for('server_module.view',
                                                 server_id=svr['id'])})
    if 'sshkeys' in app.config['installed_blueprints']:
        ssh = SshKeyManager(client)

        for key in ssh.list_keys():
            if term.match(key['label']) or term.match(key['fingerprint']):
                text = '%s (%s)' % (key['label'], key['fingerprint'])
                text = term.sub(match_string, text)

                results.append({'label': '<strong>SSH Key:</strong> ' + text,
                                'value': url_for('ssh_module.view',
                                                 key_id=key['id'])})

    return results
Ejemplo n.º 20
0
    def on_get(self, req, resp, tenant_id=None):
        client = req.env['sl_client']
        cci = CCIManager(client)

        params = get_list_params(req)

        sl_instances = cci.list_instances(**params)
        if not isinstance(sl_instances, list):
            sl_instances = [sl_instances]

        results = []
        for instance in sl_instances:
            results.append(get_server_details_dict(self.app, req, instance))

        resp.status = 200
        resp.body = {'servers': results}
Ejemplo n.º 21
0
    def on_get(self, req, resp, tenant_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        all_options = cci.get_create_options()

        results = []
        # Load and sort all data centers
        for option in all_options['datacenters']:
            name = lookup(option, 'template', 'datacenter', 'name')

            results.append({'zoneState': {'available': True}, 'hosts': None,
                            'zoneName': name})
        results = sorted(results, key=lambda x: x['zoneName'])

        resp.body = {'availabilityZoneInfo': results}
Ejemplo n.º 22
0
    def on_put(self, req, resp, tenant_id, server_id):
        client = req.env['sl_client']
        cci = CCIManager(client)
        body = json.loads(req.stream.read().decode())

        if 'name' in lookup(body, 'server'):
            if lookup(body, 'server', 'name').strip() == '':
                return bad_request(resp, message='Server name is blank')

            cci.edit(server_id, hostname=lookup(body, 'server', 'name'))

        instance = cci.get_instance(server_id,
                                    mask=get_virtual_guest_mask())

        results = get_server_details_dict(self.app, req, instance)
        resp.body = {'server': results}
Ejemplo n.º 23
0
 def execute(self, args):
     cci = CCIManager(self.client)
     data = {}
     data['cpus'] = args.get('--cpu')
     data['memory'] = args.get('--memory')
     data['nic_speed'] = args.get('--network')
     data['public'] = True
     if args.get('--private'):
         data['public'] = False
     data = self.verify_upgrade_parameters(data)
     cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')
     if args['--really'] or confirm(
             "This action will incur charges on your account. "
             "Continue?"):
         if not cci.upgrade(cci_id, **data):
             raise CLIAbort('CCI Upgrade Failed')
Ejemplo n.º 24
0
    def on_get(self, req, resp, tenant_id=None):
        client = req.env['sl_client']
        cci = CCIManager(client)

        params = get_list_params(req)

        sl_instances = cci.list_instances(**params)
        if not isinstance(sl_instances, list):
            sl_instances = [sl_instances]

        results = []
        for instance in sl_instances:
            results.append(get_server_details_dict(self.app, req, instance))

        resp.status = 200
        resp.body = {'servers': results}
Ejemplo n.º 25
0
 def __init__(self, config, client=None):
     self.config = config
     if client is None:
         client = Client(
             auth=self.config['auth'],
             endpoint_url=self.config['endpoint_url'])
     self.client = client
     self.ssh = SshKeyManager(client)
     self.instances = CCIManager(client)
Ejemplo n.º 26
0
    def on_get(self, req, resp, tenant_id, server_id, network_label):
        network_label = network_label.lower()

        network_mask = None
        if network_label == 'public':
            network_mask = 'primaryIpAddress'
        elif network_label == 'private':
            network_mask = 'primaryBackendIpAddress'
        else:
            return not_found(resp, message='Network does not exist')

        client = req.env['sl_client']
        cci = CCIManager(client)
        instance = cci.get_instance(server_id, mask='id, ' + network_mask)

        resp.body = {
            network_label: [
                {'version': 4, 'addr': instance[network_mask]},
            ]
        }
Ejemplo n.º 27
0
    def on_get(self, req, resp, tenant_id, server_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        instance = cci.get_instance(
            server_id, mask='id, primaryIpAddress, primaryBackendIpAddress')

        addresses = {}
        if instance.get('primaryIpAddress'):
            addresses['public'] = [{
                'version': 4,
                'addr': instance['primaryIpAddress'],
            }]

        if instance.get('primaryBackendIpAddress'):
            addresses['private'] = [{
                'version': 4,
                'addr': instance['primaryBackendIpAddress'],
            }]

        resp.body = {'addresses': addresses}
Ejemplo n.º 28
0
    def on_get(self, req, resp, tenant_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        all_options = cci.get_create_options()

        results = []
        # Load and sort all data centers
        for option in all_options['datacenters']:
            name = lookup(option, 'template', 'datacenter', 'name')

            results.append({
                'zoneState': {
                    'available': True
                },
                'hosts': None,
                'zoneName': name
            })
        results = sorted(results, key=lambda x: x['zoneName'])

        resp.body = {'availabilityZoneInfo': results}
Ejemplo n.º 29
0
    def on_get(self, req, resp, tenant_id, target_id):
        client = req.env['sl_client']
        cci = CCIManager(client)
        start_time = datetime.datetime.now() + datetime.timedelta(hours=-1)
        usage = {
            'server_usages': [],
            'start': start_time.isoformat(),
            'stop': datetime.datetime.now().isoformat(),
            'tenant_id': target_id,
            'total_hours': 0.0,
            'total_local_gb_usage': 0.0,
            'total_memory_mb_usage': 0.0,
            'total_vcpus_usage': 0.0,
        }

        params = {
            'mask': get_virtual_guest_mask(),
        }

        for instance in cci.list_instances(**params):
            server_dict = {
                'ended_at': None,
                'flavor': 'custom',
                'hours': 0.0,
                'instance_id': instance['id'],
                'local_gb': 1,
                'memory_mb': instance['maxMemory'],
                'name': instance['hostname'],
                'started_at': instance.get('provisionDate'),
                'state': instance['status']['keyName'].lower(),
                'tenant_id': target_id,
                'uptime': 3600,
                'vcpus': instance['maxCpu'],
            }
            usage['total_vcpus_usage'] += instance['maxCpu']
            usage['total_memory_mb_usage'] += instance['maxMemory']
            usage['server_usages'].append(server_dict)

        resp.body = {'tenant_usage': usage}
Ejemplo n.º 30
0
    def execute(self, args):
        cci = CCIManager(self.client)

        tags = None
        if args.get('--tags'):
            tags = [tag.strip() for tag in args.get('--tags').split(',')]

        guests = cci.list_instances(
            hourly=args.get('--hourly'),
            monthly=args.get('--monthly'),
            hostname=args.get('--hostname'),
            domain=args.get('--domain'),
            cpus=args.get('--cpu'),
            memory=args.get('--memory'),
            datacenter=args.get('--datacenter'),
            nic_speed=args.get('--network'),
            tags=tags)

        t = Table([
            'id', 'datacenter', 'host',
            'cores', 'memory', 'primary_ip',
            'backend_ip', 'active_transaction',
        ])
        t.sortby = args.get('--sortby') or 'host'

        for guest in guests:
            guest = NestedDict(guest)
            t.add_row([
                guest['id'],
                guest['datacenter']['name'] or blank(),
                guest['fullyQualifiedDomainName'],
                guest['maxCpu'],
                mb_to_gb(guest['maxMemory']),
                guest['primaryIpAddress'] or blank(),
                guest['primaryBackendIpAddress'] or blank(),
                active_txn(guest),
            ])

        return t
Ejemplo n.º 31
0
    def on_get(self, req, resp, tenant_id, server_id):
        client = req.env['sl_client']
        cci = CCIManager(client)

        instance = cci.get_instance(
            server_id, mask='id, primaryIpAddress, primaryBackendIpAddress')

        addresses = {}
        if instance.get('primaryIpAddress'):
            addresses['public'] = [{
                'version': 4,
                'addr': instance['primaryIpAddress'],
            }]

        if instance.get('primaryBackendIpAddress'):
            addresses['private'] = [{
                'version':
                4,
                'addr':
                instance['primaryBackendIpAddress'],
            }]

        resp.body = {'addresses': addresses}
Ejemplo n.º 32
0
    def on_get(self, req, resp, tenant_id, server_id, network_label):
        network_label = network_label.lower()

        network_mask = None
        if network_label == 'public':
            network_mask = 'primaryIpAddress'
        elif network_label == 'private':
            network_mask = 'primaryBackendIpAddress'
        else:
            return not_found(resp, message='Network does not exist')

        client = req.env['sl_client']
        cci = CCIManager(client)
        instance = cci.get_instance(server_id, mask='id, ' + network_mask)

        resp.body = {
            network_label: [
                {
                    'version': 4,
                    'addr': instance[network_mask]
                },
            ]
        }
Ejemplo n.º 33
0
    def on_get(self, req, resp, tenant_id):
        client = req.env["sl_client"]
        cci = CCIManager(client)

        params = get_list_params(req)

        sl_instances = cci.list_instances(**params)
        if not isinstance(sl_instances, list):
            sl_instances = [sl_instances]

        results = []
        for instance in sl_instances:
            results.append(
                {
                    "id": instance["id"],
                    "links": [
                        {"href": self.app.get_endpoint_url("compute", req, "v2_server", server_id=id), "rel": "self"}
                    ],
                    "name": instance["hostname"],
                }
            )

        resp.status = 200
        resp.body = {"servers": results}
Ejemplo n.º 34
0
class CCITests(unittest.TestCase):
    """
    Small class to verify the rename of CCIManager to VSManager didn't
    break any existing code.
    """
    def setUp(self):
        self.client = FixtureClient()
        self.cci = CCIManager(self.client)

    def test_list_instances(self):
        mcall = call(mask=ANY, filter={})
        service = self.client['Account']

        list_expected_ids = [100, 104]
        hourly_expected_ids = [104]
        monthly_expected_ids = [100]

        results = self.cci.list_instances(hourly=True, monthly=True)
        service.getVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], list_expected_ids)

        result = self.cci.list_instances(hourly=False, monthly=False)
        service.getVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], list_expected_ids)

        results = self.cci.list_instances(hourly=False, monthly=True)
        service.getMonthlyVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], monthly_expected_ids)

        results = self.cci.list_instances(hourly=True, monthly=False)
        service.getHourlyVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], hourly_expected_ids)
Ejemplo n.º 35
0
    def on_post(self, req, resp, tenant_id, instance_id):
        body = json.loads(req.stream.read().decode())

        if len(body) == 0:
            return bad_request(resp, message="Malformed request body")

        vg_client = req.env['sl_client']['Virtual_Guest']
        cci = CCIManager(req.env['sl_client'])

        try:
            instance_id = int(instance_id)
        except ValueError:
            return not_found(resp, "Invalid instance ID specified.")

        instance = cci.get_instance(instance_id)

        if 'pause' in body or 'suspend' in body:
            try:
                vg_client.pause(id=instance_id)
            except SoftLayerAPIError as e:
                if 'Unable to pause instance' in e.faultString:
                    return duplicate(resp, e.faultString)
                raise
            resp.status = 202
            return
        elif 'unpause' in body or 'resume' in body:
            vg_client.resume(id=instance_id)
            resp.status = 202
            return
        elif 'reboot' in body:
            if body['reboot'].get('type') == 'SOFT':
                vg_client.rebootSoft(id=instance_id)
            elif body['reboot'].get('type') == 'HARD':
                vg_client.rebootHard(id=instance_id)
            else:
                vg_client.rebootDefault(id=instance_id)
            resp.status = 202
            return
        elif 'os-stop' in body:
            vg_client.powerOff(id=instance_id)
            resp.status = 202
            return
        elif 'os-start' in body:
            vg_client.powerOn(id=instance_id)
            resp.status = 202
            return
        elif 'createImage' in body:
            image_name = body['createImage']['name']
            disks = []

            for disk in filter(lambda x: x['device'] == '0',
                               instance['blockDevices']):
                disks.append(disk)

            try:
                vg_client.createArchiveTransaction(
                    image_name,
                    disks,
                    "Auto-created by OpenStack compatibility layer",
                    id=instance_id,
                )
                # Workaround for not having an image guid until the image is
                # fully created. TODO: Fix this
                cci.wait_for_transaction(instance_id, 300)
                _filter = {
                    'privateBlockDeviceTemplateGroups': {
                        'name': {
                            'operation': image_name
                        },
                        'createDate': {
                            'operation': 'orderBy',
                            'options': [{
                                'name': 'sort',
                                'value': ['DESC']
                            }],
                        }
                    }
                }

                acct = req.env['sl_client']['Account']
                matching_image = acct.getPrivateBlockDeviceTemplateGroups(
                    mask='id, globalIdentifier', filter=_filter, limit=1)
                image_guid = matching_image.get('globalIdentifier')

                url = self.app.get_endpoint_url('image',
                                                req,
                                                'v2_image',
                                                image_guid=image_guid)

                resp.status = 202
                resp.set_header('location', url)
            except SoftLayerAPIError as e:
                compute_fault(resp, e.faultString)
            return
        elif 'os-getConsoleOutput' in body:
            resp.status = 501
            return

        return bad_request(resp,
                           message="There is no such action: %s" %
                           list(body.keys()),
                           code=400)
Ejemplo n.º 36
0
class SoftLayer(object):

    def __init__(self, config, client=None):
        self.config = config
        if client is None:
            client = Client(
                auth=self.config['auth'],
                endpoint_url=self.config['endpoint_url'])
        self.client = client
        self.ssh = SshKeyManager(client)
        self.instances = CCIManager(client)

    @classmethod
    def get_config(cls):
        provider_conf = client_conf.get_client_settings()
        if 'SL_SSH_KEY' in os.environ:
            provider_conf['ssh_key'] = os.environ['SL_SSH_KEY']
        if not ('auth' in provider_conf and 'endpoint_url' in provider_conf):
            raise ConfigError("Missing digital ocean api credentials")
        return provider_conf

    def get_ssh_keys(self):
        keys = map(SSHKey, self.ssh.list_keys())
        if 'ssh_key' in self.config:
            keys = [k for k in keys if k.name == self.config['ssh_key']]
        log.debug(
            "Using SoftLayer ssh keys: %s" % ", ".join(k.name for k in keys))
        return keys

    def get_instances(self):
        return map(Instance, self.instances.list_instances())

    def get_instance(self, instance_id):
        return Instance(self.instances.get_instance(instance_id))

    def launch_instance(self, params):
        return Instance(self.instances.create_instance(**params))

    def terminate_instance(self, instance_id):
        self.instances.cancel_instance(instance_id)

    def wait_on(self, instance):
        # Wait up to 5 minutes, in 30 sec increments
        result = self._wait_on_instance(instance, 30, 10)
        if not result:
            raise ProviderError("Could not provision instance before timeout")
        return result

    def _wait_on_instance(self, instance, limit, delay=10):
        # Redo cci.wait to give user feedback in verbose mode.
        for count, new_instance in enumerate(itertools.repeat(instance.id)):
            instance = self.get_instance(new_instance)
            if not instance.get('activeTransaction', {}).get('id') and \
               instance.get('provisionDate'):
                return True
            if count >= limit:
                return False
            if count and count % 3 == 0:
                log.debug("Waiting for instance:%s ip:%s waited:%ds" % (
                    instance.name, instance.ip_address, count*delay))
            time.sleep(delay)
Ejemplo n.º 37
0
 def setUp(self):
     self.client = MagicMock()
     self.cci = CCIManager(self.client)
     self.guestObject = self.client['Virtual_Guest'].getObject
Ejemplo n.º 38
0
class CCIWaitReadyGoTests(unittest.TestCase):

    def setUp(self):
        self.client = MagicMock()
        self.cci = CCIManager(self.client)
        self.guestObject = self.client['Virtual_Guest'].getObject

    @patch('SoftLayer.managers.cci.CCIManager.wait_for_ready')
    def test_wait_interface(self, ready):
        # verify interface to wait_for_ready is intact
        self.cci.wait_for_transaction(1, 1)
        ready.assert_called_once_with(1, 1, delay=1, pending=True)

    def test_active_not_provisioned(self):
        # active transaction and no provision date should be false
        self.guestObject.side_effect = [
            {'activeTransaction': {'id': 1}},
        ]
        value = self.cci.wait_for_ready(1, 1)
        self.assertFalse(value)

    def test_active_and_provisiondate(self):
        # active transaction and provision date should be True
        self.guestObject.side_effect = [
            {'activeTransaction': {'id': 1},
             'provisionDate': 'aaa'},
        ]
        value = self.cci.wait_for_ready(1, 1)
        self.assertTrue(value)

    def test_active_provision_pending(self):
        # active transaction and provision date
        # and pending should be false
        self.guestObject.side_effect = [
            {'activeTransaction': {'id': 1},
             'provisionDate': 'aaa'},
        ]
        value = self.cci.wait_for_ready(1, 1, pending=True)
        self.assertFalse(value)

    def test_active_reload(self):
        # actively running reload
        self.guestObject.side_effect = [
            {
                'activeTransaction': {'id': 1},
                'provisionDate': 'aaa',
                'lastOperatingSystemReload': {'id': 1},
            },
        ]
        value = self.cci.wait_for_ready(1, 1)
        self.assertFalse(value)

    def test_reload_no_pending(self):
        # reload complete, maintance transactions
        self.guestObject.side_effect = [
            {
                'activeTransaction': {'id': 2},
                'provisionDate': 'aaa',
                'lastOperatingSystemReload': {'id': 1},
            },
        ]
        value = self.cci.wait_for_ready(1, 1)
        self.assertTrue(value)

    def test_reload_pending(self):
        # reload complete, pending maintance transactions
        self.guestObject.side_effect = [
            {
                'activeTransaction': {'id': 2},
                'provisionDate': 'aaa',
                'lastOperatingSystemReload': {'id': 1},
            },
        ]
        value = self.cci.wait_for_ready(1, 1, pending=True)
        self.assertFalse(value)

    @patch('SoftLayer.managers.cci.sleep')
    def test_ready_iter_once_incomplete(self, _sleep):
        self.guestObject = self.client['Virtual_Guest'].getObject

        # no iteration, false
        self.guestObject.side_effect = [
            {'activeTransaction': {'id': 1}},
        ]
        value = self.cci.wait_for_ready(1, 1)
        self.assertFalse(value)
        self.assertFalse(_sleep.called)

    @patch('SoftLayer.managers.cci.sleep')
    def test_iter_once_complete(self, _sleep):
        # no iteration, true
        self.guestObject.side_effect = [
            {'provisionDate': 'aaa'},
        ]
        value = self.cci.wait_for_ready(1, 1)
        self.assertTrue(value)
        self.assertFalse(_sleep.called)

    @patch('SoftLayer.managers.cci.sleep')
    def test_iter_four_complete(self, _sleep):
        # test 4 iterations with positive match
        self.guestObject.side_effect = [
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'provisionDate': 'aaa'},
        ]

        value = self.cci.wait_for_ready(1, 4)
        self.assertTrue(value)
        _sleep.assert_has_calls([call(1), call(1), call(1)])
        self.guestObject.assert_has_calls([
            call(id=1, mask=ANY), call(id=1, mask=ANY),
            call(id=1, mask=ANY), call(id=1, mask=ANY),
        ])

    @patch('SoftLayer.managers.cci.sleep')
    def test_iter_two_incomplete(self, _sleep):
        # test 2 iterations, with no matches
        self.guestObject.side_effect = [
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'provisionDate': 'aaa'}
        ]
        value = self.cci.wait_for_ready(1, 2)
        self.assertFalse(value)
        _sleep.assert_called_once_with(1)
        self.guestObject.assert_has_calls([
            call(id=1, mask=ANY), call(id=1, mask=ANY),
        ])

    @patch('SoftLayer.managers.cci.sleep')
    def test_iter_ten_incomplete(self, _sleep):
        # 10 iterations at 10 second sleeps with no
        # matching values.
        self.guestObject.side_effect = [
            {},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
            {'activeTransaction': {'id': 1}},
        ]
        value = self.cci.wait_for_ready(1, 10, delay=10)
        self.assertFalse(value)
        self.guestObject.assert_has_calls([
            call(id=1, mask=ANY), call(id=1, mask=ANY),
            call(id=1, mask=ANY), call(id=1, mask=ANY),
            call(id=1, mask=ANY), call(id=1, mask=ANY),
            call(id=1, mask=ANY), call(id=1, mask=ANY),
            call(id=1, mask=ANY), call(id=1, mask=ANY),
        ])
        # should only be 9 calls to sleep, last iteration
        # should return a value and skip the sleep
        _sleep.assert_has_calls([
            call(10), call(10), call(10), call(10), call(10),
            call(10), call(10), call(10), call(10)])
Ejemplo n.º 39
0
 def setUp(self):
     self.client = FixtureClient()
     self.cci = CCIManager(self.client)
Ejemplo n.º 40
0
class CCITests(unittest.TestCase):

    def setUp(self):
        self.client = FixtureClient()
        self.cci = CCIManager(self.client)

    def test_list_instances(self):
        mcall = call(mask=ANY, filter={})
        service = self.client['Account']

        list_expected_ids = [100, 104]
        hourly_expected_ids = [104]
        monthly_expected_ids = [100]

        results = self.cci.list_instances(hourly=True, monthly=True)
        service.getVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], list_expected_ids)

        result = self.cci.list_instances(hourly=False, monthly=False)
        service.getVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], list_expected_ids)

        results = self.cci.list_instances(hourly=False, monthly=True)
        service.getMonthlyVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], monthly_expected_ids)

        results = self.cci.list_instances(hourly=True, monthly=False)
        service.getHourlyVirtualGuests.assert_has_calls(mcall)
        for result in results:
            self.assertIn(result['id'], hourly_expected_ids)

    def test_list_instances_with_filters(self):
        self.cci.list_instances(
            hourly=True,
            monthly=True,
            tags=['tag1', 'tag2'],
            cpus=2,
            memory=1024,
            hostname='hostname',
            domain='example.com',
            local_disk=True,
            datacenter='dal05',
            nic_speed=100,
            public_ip='1.2.3.4',
            private_ip='4.3.2.1',
        )

        service = self.client['Account']
        service.getVirtualGuests.assert_has_calls(call(
            filter={
                'virtualGuests': {
                    'datacenter': {
                        'name': {'operation': '_= dal05'}},
                    'domain': {'operation': '_= example.com'},
                    'tagReferences': {
                        'tag': {'name': {
                            'operation': 'in',
                            'options': [{
                                'name': 'data', 'value': ['tag1', 'tag2']}]}}},
                    'maxCpu': {'operation': 2},
                    'localDiskFlag': {'operation': True},
                    'maxMemory': {'operation': 1024},
                    'hostname': {'operation': '_= hostname'},
                    'networkComponents': {'maxSpeed': {'operation': 100}},
                    'primaryIpAddress': {'operation': '_= 1.2.3.4'},
                    'primaryBackendIpAddress': {'operation': '_= 4.3.2.1'}
                }},
            mask=ANY,
        ))

    def test_resolve_ids_ip(self):
        service = self.client['Account']
        _id = self.cci._get_ids_from_ip('172.16.240.2')
        self.assertEqual(_id, [100, 104])

        _id = self.cci._get_ids_from_ip('nope')
        self.assertEqual(_id, [])

        # Now simulate a private IP test
        service.getVirtualGuests.side_effect = [[], [{'id': 99}]]
        _id = self.cci._get_ids_from_ip('10.0.1.87')
        self.assertEqual(_id, [99])

    def test_resolve_ids_hostname(self):
        _id = self.cci._get_ids_from_hostname('cci-test1')
        self.assertEqual(_id, [100, 104])

    def test_get_instance(self):
        result = self.cci.get_instance(100)
        self.client['Virtual_Guest'].getObject.assert_called_once_with(
            id=100, mask=ANY)
        self.assertEqual(Virtual_Guest.getObject, result)

    def test_get_create_options(self):
        results = self.cci.get_create_options()
        self.assertEqual(Virtual_Guest.getCreateObjectOptions, results)

    def test_cancel_instance(self):
        self.cci.cancel_instance(1)
        self.client['Virtual_Guest'].deleteObject.assert_called_once_with(id=1)

    def test_reload_instance(self):
        post_uri = 'http://test.sftlyr.ws/test.sh'
        self.cci.reload_instance(1, post_uri=post_uri, ssh_keys=[1701])
        service = self.client['Virtual_Guest']
        f = service.reloadOperatingSystem
        f.assert_called_once_with('FORCE',
                                  {'customProvisionScriptUri': post_uri,
                                   'sshKeyIds': [1701]}, id=1)

    @patch('SoftLayer.managers.cci.CCIManager._generate_create_dict')
    def test_create_verify(self, create_dict):
        create_dict.return_value = {'test': 1, 'verify': 1}
        self.cci.verify_create_instance(test=1, verify=1)
        create_dict.assert_called_once_with(test=1, verify=1)
        f = self.client['Virtual_Guest'].generateOrderTemplate
        f.assert_called_once_with({'test': 1, 'verify': 1})

    @patch('SoftLayer.managers.cci.CCIManager._generate_create_dict')
    def test_create_instance(self, create_dict):
        create_dict.return_value = {'test': 1, 'verify': 1}
        self.cci.create_instance(test=1, verify=1)
        create_dict.assert_called_once_with(test=1, verify=1)
        self.client['Virtual_Guest'].createObject.assert_called_once_with(
            {'test': 1, 'verify': 1})

    def test_generate_os_and_image(self):
        self.assertRaises(
            ValueError,
            self.cci._generate_create_dict,
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code=1,
            image_id=1,
        )

    def test_generate_missing(self):
        self.assertRaises(ValueError, self.cci._generate_create_dict)
        self.assertRaises(ValueError, self.cci._generate_create_dict, cpus=1)

    def test_generate_basic(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
        }

        self.assertEqual(data, assert_data)

    def test_generate_monthly(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            hourly=False,
        )

        assert_data = {
            'hourlyBillingFlag': False,
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
        }

        self.assertEqual(data, assert_data)

    def test_generate_image_id(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            image_id="45",
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'blockDeviceTemplateGroup': {"globalIdentifier": "45"},
            'hourlyBillingFlag': True,
        }

        self.assertEqual(data, assert_data)

    def test_generate_dedicated(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            dedicated=True,
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'dedicatedAccountHostOnlyFlag': True,
        }

        self.assertEqual(data, assert_data)

    def test_generate_datacenter(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            datacenter="sng01",
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'datacenter': {"name": 'sng01'},
        }

        self.assertEqual(data, assert_data)

    def test_generate_public_vlan(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            public_vlan=1,
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'primaryNetworkComponent': {"networkVlan": {"id": 1}},
        }

        self.assertEqual(data, assert_data)

    def test_generate_private_vlan(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            private_vlan=1,
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'primaryBackendNetworkComponent': {"networkVlan": {"id": 1}},
        }

        self.assertEqual(data, assert_data)

    def test_generate_userdata(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            userdata="ICANHAZCCI",
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'userData': [{'value': "ICANHAZCCI"}],
        }

        self.assertEqual(data, assert_data)

    def test_generate_network(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            nic_speed=9001,
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'networkComponents': [{'maxSpeed': 9001}],
        }

        self.assertEqual(data, assert_data)

    def test_generate_private_network_only(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            nic_speed=9001,
            private=True
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'privateNetworkOnlyFlag': True,
            'hourlyBillingFlag': True,
            'networkComponents': [{'maxSpeed': 9001}],
        }

        self.assertEqual(data, assert_data)

    def test_generate_post_uri(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            post_uri='https://example.com/boostrap.sh',
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'postInstallScriptUri': 'https://example.com/boostrap.sh',
        }

        self.assertEqual(data, assert_data)

    def test_generate_sshkey(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            ssh_keys=[543],
        )

        assert_data = {
            'startCpus': 1,
            'maxMemory': 1,
            'hostname': 'test',
            'domain': 'example.com',
            'localDiskFlag': True,
            'operatingSystemReferenceCode': "STRING",
            'hourlyBillingFlag': True,
            'sshKeys': [{'id': 543}],
        }

        self.assertEqual(data, assert_data)

    def test_generate_no_disks(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING"
        )

        self.assertEqual(data.get('blockDevices'), None)

    def test_generate_single_disk(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            disks=[50]
        )

        assert_data = {
            'blockDevices': [
                {"device": "0", "diskImage": {"capacity": 50}}]
        }

        self.assertTrue(data.get('blockDevices'))
        self.assertEqual(data['blockDevices'], assert_data['blockDevices'])

    def test_generate_multi_disk(self):
        data = self.cci._generate_create_dict(
            cpus=1,
            memory=1,
            hostname='test',
            domain='example.com',
            os_code="STRING",
            disks=[50, 70, 100]
        )

        assert_data = {
            'blockDevices': [
                {"device": "0", "diskImage": {"capacity": 50}},
                {"device": "2", "diskImage": {"capacity": 70}},
                {"device": "3", "diskImage": {"capacity": 100}}]
        }

        self.assertTrue(data.get('blockDevices'))
        self.assertEqual(data['blockDevices'], assert_data['blockDevices'])

    def test_change_port_speed_public(self):
        cci_id = 1
        speed = 100
        self.cci.change_port_speed(cci_id, True, speed)

        service = self.client['Virtual_Guest']
        f = service.setPublicNetworkInterfaceSpeed
        f.assert_called_once_with(speed, id=cci_id)

    def test_change_port_speed_private(self):
        cci_id = 2
        speed = 10
        self.cci.change_port_speed(cci_id, False, speed)

        service = self.client['Virtual_Guest']
        f = service.setPrivateNetworkInterfaceSpeed
        f.assert_called_once_with(speed, id=cci_id)

    def test_edit(self):
        # Test editing user data
        service = self.client['Virtual_Guest']

        self.cci.edit(100, userdata='my data')

        service.setUserMetadata.assert_called_once_with(['my data'], id=100)

        # Now test a blank edit
        self.assertTrue(self.cci.edit, 100)

        # Finally, test a full edit
        args = {
            'hostname': 'new-host',
            'domain': 'new.sftlyr.ws',
            'notes': 'random notes',
        }

        self.cci.edit(100, **args)
        service.editObject.assert_called_once_with(args, id=100)
Ejemplo n.º 41
0
from django.core.management.base import BaseCommand, CommandError
from slsync.models import Inst


class Command(BaseCommand):
    #empty the staging table for import
    Inst.objects.all().delete()


from SoftLayer import Client, CCIManager
from SoftLayer.CLI.helpers import (NestedDict)
import os
sl_api_user = os.environ['SL_API_USER']
sl_api_key = os.environ['SL_API_KEY']
client = Client(username=sl_api_user, api_key=sl_api_key)

cci = CCIManager(client)
guests = cci.list_instances()
for guest in guests:
    guest = NestedDict(guest)
    a = Inst(inst_id=guest['id'],
             pub_ip=guest['primaryIpAddress'],
             pri_ip=guest['primaryBackendIpAddress'],
             fulldomainname=guest['fullyQualifiedDomainName'])
    a.save()
Ejemplo n.º 42
0
def get_vm_manager():
    return CCIManager(get_client())
Ejemplo n.º 43
0
    def dns_sync(self, args):
        """ Sync DNS records to match the FQDN of the CCI """
        dns = DNSManager(self.client)
        cci = CCIManager(self.client)

        cci_id = resolve_id(cci.resolve_ids, args.get('<identifier>'), 'CCI')
        instance = cci.get_instance(cci_id)
        zone_id = resolve_id(dns.resolve_ids, instance['domain'], name='zone')

        def sync_a_record():
            """ Sync A record """
            records = dns.get_records(
                zone_id,
                host=instance['hostname'],
            )

            if not records:
                # don't have a record, lets add one to the base zone
                dns.create_record(
                    zone['id'],
                    instance['hostname'],
                    'a',
                    instance['primaryIpAddress'],
                    ttl=args['--ttl'])
            else:
                recs = [x for x in records if x['type'].lower() == 'a']
                if len(recs) != 1:
                    raise CLIAbort("Aborting A record sync, found %d "
                                   "A record exists!" % len(recs))
                rec = recs[0]
                rec['data'] = instance['primaryIpAddress']
                rec['ttl'] = args['--ttl']
                dns.edit_record(rec)

        def sync_ptr_record():
            """ Sync PTR record """
            host_rec = instance['primaryIpAddress'].split('.')[-1]
            ptr_domains = self.client['Virtual_Guest'].\
                getReverseDomainRecords(id=instance['id'])[0]
            edit_ptr = None
            for ptr in ptr_domains['resourceRecords']:
                if ptr['host'] == host_rec:
                    ptr['ttl'] = args['--ttl']
                    edit_ptr = ptr
                    break

            if edit_ptr:
                edit_ptr['data'] = instance['fullyQualifiedDomainName']
                dns.edit_record(edit_ptr)
            else:
                dns.create_record(
                    ptr_domains['id'],
                    host_rec,
                    'ptr',
                    instance['fullyQualifiedDomainName'],
                    ttl=args['--ttl'])

        if not instance['primaryIpAddress']:
            raise CLIAbort('No primary IP address associated with this CCI')

        try:
            zone = dns.get_zone(zone_id)
        except DNSZoneNotFound:
            raise CLIAbort("Unable to create A record, "
                           "no zone found matching: %s" % instance['domain'])

        go_for_it = args['--really'] or confirm(
            "Attempt to update DNS records for %s"
            % instance['fullyQualifiedDomainName'])

        if not go_for_it:
            raise CLIAbort("Aborting DNS sync")

        both = False
        if not args['--ptr'] and not args['-a']:
            both = True

        if both or args['-a']:
            sync_a_record()

        if both or args['--ptr']:
            sync_ptr_record()
Ejemplo n.º 44
0
    def on_post(self, req, resp, tenant_id):
        client = req.env['sl_client']
        body = json.loads(req.stream.read().decode())
        flavor_id = int(body['server'].get('flavorRef'))
        if flavor_id not in FLAVORS:
            return bad_request(resp, 'Flavor could not be found')

        flavor = FLAVORS[flavor_id]

        ssh_keys = []
        key_name = body['server'].get('key_name')
        if key_name:
            sshkey_mgr = SshKeyManager(client)
            keys = sshkey_mgr.list_keys(label=key_name)
            if len(keys) == 0:
                return bad_request(resp, 'KeyPair could not be found')
            ssh_keys.append(keys[0]['id'])

        private_network_only = False
        networks = lookup(body, 'server', 'networks')
        if networks:
            # Make sure they're valid networks
            if not all([
                    network['uuid'] in ['public', 'private'] in network
                    for network in networks
            ]):
                return bad_request(resp, message='Invalid network')

            # Find out if it's private only
            if not any([
                    network['uuid'] == 'public' in network
                    for network in networks
            ]):
                private_network_only = True

        user_data = {}
        if lookup(body, 'server', 'metadata'):
            user_data['metadata'] = lookup(body, 'server', 'metadata')
        if lookup(body, 'server', 'user_data'):
            user_data['user_data'] = lookup(body, 'server', 'user_data')
        if lookup(body, 'server', 'personality'):
            user_data['personality'] = lookup(body, 'server', 'personality')

        datacenter = None
        if lookup(body, 'server', 'availability_zone'):
            datacenter = lookup(body, 'server', 'availability_zone')

        cci = CCIManager(client)

        payload = {
            'hostname': body['server']['name'],
            'domain': 'jumpgate.com',  # TODO - Don't hardcode this
            'cpus': flavor['cpus'],
            'memory': flavor['ram'],
            'hourly': True,  # TODO - How do we set this accurately?
            'datacenter': datacenter,
            'image_id': body['server']['imageRef'],
            'ssh_keys': ssh_keys,
            'private': private_network_only,
            'userdata': json.dumps(user_data),
        }

        try:
            new_instance = cci.create_instance(**payload)
        except ValueError as e:
            return bad_request(resp, message=str(e))

        resp.set_header('x-compute-request-id', 'create')
        resp.status = 202
        resp.body = {
            'server': {
                'id':
                new_instance['id'],
                'links': [{
                    'href':
                    self.app.get_endpoint_url('compute',
                                              req,
                                              'v2_server',
                                              instance_id=new_instance['id']),
                    'rel':
                    'self'
                }],
                'adminPass':
                '',
            }
        }
Ejemplo n.º 45
0
    def execute(self, args):
        update_with_template_args(args)
        cci = CCIManager(self.client)
        self._update_with_like_args(args)

        # Disks will be a comma-separated list. Let's make it a real list.
        if isinstance(args.get('--disk'), str):
            args['--disk'] = args.get('--disk').split(',')

        # SSH keys may be a comma-separated list. Let's make it a real list.
        if isinstance(args.get('--key'), str):
            args['--key'] = args.get('--key').split(',')

        self._validate_args(args)

        # Do not create CCI with --test or --export
        do_create = not (args['--export'] or args['--test'])

        table = Table(['Item', 'cost'])
        table.align['Item'] = 'r'
        table.align['cost'] = 'r'
        data = self._parse_create_args(args)

        output = []
        if args.get('--test'):
            result = cci.verify_create_instance(**data)
            total_monthly = 0.0
            total_hourly = 0.0

            table = Table(['Item', 'cost'])
            table.align['Item'] = 'r'
            table.align['cost'] = 'r'

            for price in result['prices']:
                total_monthly += float(price.get('recurringFee', 0.0))
                total_hourly += float(price.get('hourlyRecurringFee', 0.0))
                if args.get('--hourly'):
                    rate = "%.2f" % float(price['hourlyRecurringFee'])
                else:
                    rate = "%.2f" % float(price['recurringFee'])

                table.add_row([price['item']['description'], rate])

            if args.get('--hourly'):
                total = total_hourly
            else:
                total = total_monthly

            billing_rate = 'monthly'
            if args.get('--hourly'):
                billing_rate = 'hourly'
            table.add_row(['Total %s cost' % billing_rate, "%.2f" % total])
            output.append(table)
            output.append(FormattedItem(
                None,
                ' -- ! Prices reflected here are retail and do not '
                'take account level discounts and are not guaranteed.')
            )

        if args['--export']:
            export_file = args.pop('--export')
            export_to_template(export_file, args, exclude=['--wait', '--test'])
            return 'Successfully exported options to a template file.'

        if do_create:
            if args['--really'] or confirm(
                    "This action will incur charges on your account. "
                    "Continue?"):
                result = cci.create_instance(**data)

                table = KeyValueTable(['name', 'value'])
                table.align['name'] = 'r'
                table.align['value'] = 'l'
                table.add_row(['id', result['id']])
                table.add_row(['created', result['createDate']])
                table.add_row(['guid', result['globalIdentifier']])
                output.append(table)

                if args.get('--wait'):
                    ready = cci.wait_for_ready(
                        result['id'], int(args.get('--wait') or 1))
                    table.add_row(['ready', ready])
            else:
                raise CLIAbort('Aborting CCI order.')

        return output