コード例 #1
0
 def execute(client, args):
     cci = CCIManager(client)
     cci_id = resolve_id(cci, args.get('<identifier>'))
     if args['--really'] or no_going_back(cci_id):
         cci.cancel_instance(cci_id)
     else:
         CLIAbort('Aborted')
コード例 #2
0
    def execute(client, args):
        cci = CCIManager(client)

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

        if ready:
            return "READY"
        else:
            raise CLIAbort("Instance %s not ready" % cci_id)
コード例 #3
0
    def execute(client, args):
        cci = CCIManager(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:
            t.add_row([
                guest['id'],
                guest.get('datacenter', {}).get('name', 'unknown'),
                guest['fullyQualifiedDomainName'],
                guest['maxCpu'],
                mb_to_gb(guest['maxMemory']),
                guest.get('primaryIpAddress', blank()),
                guest.get('primaryBackendIpAddress', blank()),
                guest.get('activeTransaction', {}).get(
                    'transactionStatus', {}).get('friendlyName', blank()),
            ])

        return t
コード例 #4
0
    def execute(client, args):
        cci = CCIManager(client)

        results = cci.list_instances(
            hourly=args.get('--hourly'), monthly=args.get('--monthly'))

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

        if args.get('--tags'):
            tags = [tag.strip() for tag in args.get('--tags').split(',')]
            guests = []
            for g in results:
                guest_tags = [x['tag']['name'] for x in g['tagReferences']]
                if any(_tag in tags for _tag in guest_tags):
                    guests.append(g)
        else:
            guests = results

        for guest in guests:
            t.add_row([
                guest['id'],
                guest.get('datacenter', {}).get('name', 'unknown'),
                guest['fullyQualifiedDomainName'],
                guest['maxCpu'],
                mb_to_gb(guest['maxMemory']),
                guest.get('primaryIpAddress', '-'),
                guest.get('primaryBackendIpAddress', '-'),
                guest.get('activeTransaction', {}).get(
                    'transactionStatus', {}).get('friendlyName', '<None>'),
            ])

        return t
コード例 #5
0
 def _on_init(self):
     self._client = Client(username=getenv('SL_USERNAME'),
                           api_key=getenv('SL_API_KEY'))
     self._manager = CCIManager(self._client)
コード例 #6
0
class CCIPlatform(Platform):
    _required_opts = ['cores', 'memory', 'domain',
                      'datacenter', 'os_code']

    def _on_init(self):
        self._client = Client(username=getenv('SL_USERNAME'),
                              api_key=getenv('SL_API_KEY'))
        self._manager = CCIManager(self._client)

    def find_instance(self, host_name):
        instance = None
        host_name = host_name.lower()

        for ii in self._manager.list_instances():
            fqdn = ii.get('fullyQualifiedDomainName', '')
            if fqdn.lower() == host_name:
                instance = Instance(id=ii.get('id'), name=fqdn)
                break

        return instance

    def get_instance(self, id):
        cci = self._manager.get_instance(id)
        return self._cci_to_instance(cci)

    def create_instance(self, host_name):
        host_bits = host_name.split('.', 1)
        host_name = host_bits[0]
        domain = host_bits[1] if len(host_bits) >= 2 else self.config('domain')

        base_options = {'cpus': self.config('cores'),
                        'memory': self.config('memory'),
                        'hostname': host_name,
                        'domain': domain,
                        'datacenter': self.config('datacenter'),
                        'os_code': self.config('os_code')}

        print 'creating cci %s/%s' % (host_name, domain)
        print base_options
        cci = self._manager.create_instance(**base_options)
        cci = self._cci_await_ready(cci)

        self._cci_install_keys(cci['id'])

        return self._cci_to_instance(cci)

    def reimage_instance(self, instance):
        self._manager.reload_instance(instance.id)
        cci = self._manager.get_instance(instance.id)
        cci = self._cci_await_transaction_start(cci)
        cci = self._cci_await_ready(cci)

        self._cci_install_keys(cci['id'])

        return self._cci_to_instance(cci)

    def delete_instance(self, instance):
        self._manager.cancel_instance(instance.id)
        self._cci_await_delete(self._manager.get_instance(instance.id))

    def instance_ready(self, instance):
        cci = self._manager.get_instance(instance.id)
        return (cci and 'activeTransaction' not in cci)

    def _cci_to_instance(self, cci):
        if not cci:
            return None
        return Instance(id=cci['id'], name=cci['fullyQualifiedDomainName'])

    def _cci_await_state(self, cci, state_check, sleep_secs=5):
        wait_start = time()
        self.log_info('Waiting for %s to change state...' % (cci['id']))

        while state_check(cci):
            sleep(sleep_secs)
            cci = self._manager.get_instance(cci['id'])
            self.log_info('...')

        self.log_info('Available after %0.3f secs.' % (time() - wait_start))
        return cci

    def _cci_await_ready(self, cci):
        return self._cci_await_state(cci,
                                     lambda c: 'activeTransaction' in c,
                                     sleep_secs=5)

    def _cci_await_transaction_start(self, cci):
        return self._cci_await_state(cci,
                                     lambda c: 'activeTransaction' not in c,
                                     sleep_secs=2)

    def _cci_await_delete(self, cci):
        return self._cci_await_state(cci,
                                     lambda c: c and 'id' in c,
                                     sleep_secs=2)

    def _get_cci_root_password(self, cci):
        passwords = self._manager.get_instance_passwords(cci['id'])
        password = None

        for p in passwords:
            if 'username' in p and p['username'] == 'root':
                password = p['password']
                break

        return password

    def _cci_install_keys(self, id):
        cci = self._manager.get_instance(id)
        password = self._get_cci_root_password(cci)

        if not password:
            raise Exception('Passwords are not available for instance %s' %
                            cci['id'])

        keys_url = self.config('ssh_key_url')
        if not keys_url:
            return

        client_settings = {'hostname': cci['primaryIpAddress'],
                           'username': '******',
                           'password': password}
        client = SSHClient()
        client.set_missing_host_key_policy(_SuppressPolicy())
        client.connect(look_for_keys=False, **client_settings)

        client.exec_command('mkdir -p ~/.ssh')
        client.exec_command('wget -T 10 -q -O ~/.ssh/authorized_keys %s' %
                            keys_url)
        client.close()
コード例 #7
0
    def dns_sync(client, args):
        from SoftLayer.DNS import DNSManager, DNSZoneNotFound
        dns = DNSManager(client)
        cci = CCIManager(client)

        def sync_a_record():
            #hostname = instance['fullyQualifiedDomainName']
            records = dns.search_record(
                instance['domain'],
                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=7200)
            else:
                recs = filter(lambda x: x['type'].lower() == 'a', records)
                if len(recs) != 1:
                    raise CLIAbort("Aborting A record sync, found %d "
                                   "A record exists!" % len(recs))
                rec = recs[0]
                rec['data'] = instance['primaryIpAddress']
                dns.edit_record(rec)

        def sync_ptr_record():
            host_rec = instance['primaryIpAddress'].split('.')[-1]
            ptr_domains = client['Virtual_Guest'].\
                getReverseDomainRecords(id=instance['id'])[0]
            edit_ptr = None
            for ptr in ptr_domains['resourceRecords']:
                if ptr['host'] == host_rec:
                    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=7200)

        cci_id = resolve_id(cci, args.get('<identifier>'))
        instance = cci.get_instance(cci_id)

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

        try:
            zone = dns.get_zone(instance['domain'])
        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.get('--PTR') and not args.get('-A'):
            both = True

        if both or args.get('-A'):
            sync_a_record()

        if both or args.get('--PTR'):
            sync_ptr_record()
コード例 #8
0
    def execute(client, args):
        cci = CCIManager(client)

        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'])

        data = {
            "hourly": args['--hourly'],
            "cpus": args['--cpu'],
            "domain": args['--domain'],
            "hostname": args['--hostname'],
            "private": args['--private'],
            "local_disk": True,
        }

        try:
            memory = int(args['--memory'])
            if memory < 1024:
                memory = memory * 1024
        except ValueError:
            unit = args['--memory'][-1]
            memory = int(args['--memory'][0:-1])
            if unit in ['G', 'g']:
                memory = memory * 1024
            if unit in ['T', 'r']:
                memory = memory * 1024 * 1024

        data["memory"] = memory

        if args['--monthly']:
            data["hourly"] = False

        if args.get('--os'):
            data["os_code"] = args['--os']

        if args.get('--image'):
            data["image_id"] = args['--image']

        if args.get('--datacenter'):
            data["datacenter"] = args['--datacenter']

        if args.get('--network'):
            data['nic_speed'] = args.get('--network')

        if args.get('--userdata'):
            data['userdata'] = args['--userdata']
        elif args.get('userfile'):
            f = open(args['--userfile'], 'r')
            try:
                data['userdata'] = f.read()
            finally:
                f.close()

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

        if args.get('--test'):
            result = cci.verify_create_instance(**data)
            total_monthly = 0.0
            total_hourly = 0.0
            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'])

                t.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'
            t.add_row(['Total %s cost' % billing_rate, "%.2f" % total])
            output = SequentialOutput(blanks=False)
            output.append(t)
            output.append(FormattedItem(
                '',
                ' -- ! Prices reflected here are retail and do not '
                'take account level discounts and are not guarenteed.')
            )

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

            t = Table(['name', 'value'])
            t.align['name'] = 'r'
            t.align['value'] = 'l'
            t.add_row(['id', result['id']])
            t.add_row(['created', result['createDate']])
            t.add_row(['guid', result['globalIdentifier']])
            output = t
        else:
            raise CLIAbort('Aborting CCI order.')

        if args.get('--wait') or 0 and not args.get('--test'):
            ready = cci.wait_for_transaction(
                result['id'], int(args.get('--wait') or 1))
            t.add_row(['ready', ready])

        return output
コード例 #9
0
    def execute(cls, client, args):
        cci = CCIManager(client)
        result = cci.get_create_options()

        show_all = True
        for opt_name in cls.options:
            if args.get("--" + opt_name):
                show_all = False
                break

        if args['--all']:
            show_all = True

        t = Table(['Name', 'Value'])
        t.align['Name'] = 'r'
        t.align['Value'] = 'l'

        if args['--datacenter'] or show_all:
            datacenters = [dc['template']['datacenter']['name']
                           for dc in result['datacenters']]
            t.add_row(['datacenter', listing(datacenters, separator=',')])

        if args['--cpu'] or show_all:
            standard_cpu = filter(
                lambda x: not x['template'].get(
                    'dedicatedAccountHostOnlyFlag', False),
                result['processors'])

            ded_cpu = filter(
                lambda x: x['template'].get(
                    'dedicatedAccountHostOnlyFlag', False),
                result['processors'])

            def cpus_row(c, name):
                cpus = []
                for x in c:
                    cpus.append(str(x['template']['startCpus']))

                t.add_row(['cpus (%s)' % name, listing(cpus, separator=',')])

            cpus_row(ded_cpu, 'private')
            cpus_row(standard_cpu, 'standard')

        if args['--memory'] or show_all:
            memory = [
                str(m['template']['maxMemory']) for m in result['memory']]
            t.add_row(['memory', listing(memory, separator=',')])

        if args['--os'] or show_all:
            op_sys = [
                o['template']['operatingSystemReferenceCode'] for o in
                result['operatingSystems']]

            op_sys = sorted(op_sys)
            os_summary = set()

            for o in op_sys:
                os_summary.add(o[0:o.find('_')])

            for summary in sorted(os_summary):
                t.add_row([
                    'os (%s)' % summary,
                    linesep.join(sorted(filter(
                        lambda x: x[0:len(summary)] == summary, op_sys))
                    )
                ])

        if args['--disk'] or show_all:
            local_disks = filter(
                lambda x: x['template'].get('localDiskFlag', False),
                result['blockDevices'])

            san_disks = filter(
                lambda x: not x['template'].get('localDiskFlag', False),
                result['blockDevices'])

            def block_rows(blocks, name):
                simple = {}
                for block in blocks:
                    b = block['template']['blockDevices'][0]
                    bid = b['device']
                    size = b['diskImage']['capacity']

                    if bid not in simple:
                        simple[bid] = []

                    simple[bid].append(str(size))

                for b in sorted(simple.keys()):
                    t.add_row([
                        '%s disk(%s)' % (name, b),
                        listing(simple[b], separator=',')]
                    )

            block_rows(local_disks, 'local')
            block_rows(san_disks, 'san')

        if args['--nic'] or show_all:
            speeds = []
            for x in result['networkComponents']:
                speed = x['template']['networkComponents'][0]['maxSpeed']
                speeds.append(str(speed))

            speeds = sorted(speeds)

            t.add_row(['nic', listing(speeds, separator=',')])

        return t
コード例 #10
0
    def execute(client, args):
        cci = CCIManager(client)

        t = Table(['Name', 'Value'])
        t.align['Name'] = 'r'
        t.align['Value'] = 'l'

        cci_id = resolve_id(cci, args.get('<identifier>'))
        result = cci.get_instance(cci_id)
        result = NestedDict(result)

        t.add_row(['id', result['id']])
        t.add_row(['hostname', result['fullyQualifiedDomainName']])
        t.add_row(['status', result['status']['name']])
        t.add_row(['state', result['powerState']['name']])
        t.add_row(['datacenter', result['datacenter'].get('name', blank())])
        t.add_row(['cores', result['maxCpu']])
        t.add_row(['memory', mb_to_gb(result['maxMemory'])])
        t.add_row(['public_ip', result.get('primaryIpAddress', blank())])
        t.add_row(
            ['private_ip', result.get('primaryBackendIpAddress', blank())])
        t.add_row([
            'os',
            FormattedItem(
                result['operatingSystem']['softwareLicense']
                ['softwareDescription'].get('referenceCode', blank()),
                result['operatingSystem']['softwareLicense']
                ['softwareDescription'].get('name', blank())
            )])
        t.add_row(['private_only', result['privateNetworkOnlyFlag']])
        t.add_row(['private_cpu', result['dedicatedAccountHostOnlyFlag']])
        t.add_row(['created', result['createDate']])
        t.add_row(['modified', result['modifyDate']])

        if result.get('notes'):
            t.add_row(['notes', result['notes']])

        if args.get('--price'):
            t.add_row(['price rate', result['billingItem']['recurringFee']])

        if args.get('--passwords'):
            user_strs = []
            for item in result['operatingSystem']['passwords']:
                user_strs.append(
                    "%s %s" % (item['username'], item['password']))
            t.add_row(['users', listing(user_strs)])

        tag_row = []
        for tag in result['tagReferences']:
            tag_row.append(tag['tag']['name'])

        if tag_row:
            t.add_row(['tags', listing(tag_row, separator=',')])

        ptr_domains = client['Virtual_Guest'].\
            getReverseDomainRecords(id=cci_id)

        for ptr_domain in ptr_domains:
            for ptr in ptr_domain['resourceRecords']:
                t.add_row(['ptr', ptr['data']])

        return t
コード例 #11
0
 def execute(client, args):
     cci = CCIManager(client)
     if args['--really'] or no_going_back(args['<id>']):
         cci.cancel_instance(args['<id>'])
     else:
         CLIAbort('Aborted')