def cli(env, sortby, cpu, domain, datacenter, hostname, memory, network, tag): """List hardware servers.""" manager = SoftLayer.HardwareManager(env.client) servers = manager.list_hardware(hostname=hostname, domain=domain, cpus=cpu, memory=memory, datacenter=datacenter, nic_speed=network, tags=tag) table = formatting.Table([ 'id', 'hostname', 'primary_ip', 'backend_ip', 'datacenter', 'action', ]) table.sortby = sortby or 'hostname' for server in servers: table.add_row([ utils.lookup(server, 'id'), utils.lookup(server, 'hostname') or formatting.blank(), utils.lookup(server, 'primaryIpAddress') or formatting.blank(), utils.lookup(server, 'primaryBackendIpAddress') or formatting.blank(), utils.lookup(server, 'datacenter', 'name') or formatting.blank(), formatting.active_txn(server), ]) return table
def cli(env, sortby, cpu, domain, datacenter, hostname, memory, network, tag): """List hardware servers.""" manager = SoftLayer.HardwareManager(env.client) servers = manager.list_hardware( hostname=hostname, domain=domain, cpus=cpu, memory=memory, datacenter=datacenter, nic_speed=network, tags=tag ) table = formatting.Table(["id", "hostname", "primary_ip", "backend_ip", "datacenter", "action"]) table.sortby = sortby or "hostname" for server in servers: table.add_row( [ utils.lookup(server, "id"), utils.lookup(server, "hostname") or formatting.blank(), utils.lookup(server, "primaryIpAddress") or formatting.blank(), utils.lookup(server, "primaryBackendIpAddress") or formatting.blank(), utils.lookup(server, "datacenter", "name") or formatting.blank(), formatting.active_txn(server), ] ) return table
def wait_for_ready(self, instance_id, limit, delay=1, pending=False): """Determine if a VS is ready and available. In some cases though, that can mean that no transactions are running. The default arguments imply a VS is operational and ready for use by having network connectivity and remote access is available. Setting ``pending=True`` will ensure future API calls against this instance will not error due to pending transactions such as OS Reloads and cancellations. :param int instance_id: The instance ID with the pending transaction :param int limit: The maximum amount of time to wait. :param int delay: The number of seconds to sleep before checks. Defaults to 1. :param bool pending: Wait for pending transactions not related to provisioning or reloads such as monitoring. Example:: # Will return once vsi 12345 is ready, or after 10 checks ready = mgr.wait_for_ready(12345, 10) """ until = time.time() + limit for new_instance in itertools.repeat(instance_id): mask = """id, lastOperatingSystemReload.id, activeTransaction.id,provisionDate""" instance = self.get_instance(new_instance, mask=mask) last_reload = utils.lookup(instance, 'lastOperatingSystemReload', 'id') active_transaction = utils.lookup(instance, 'activeTransaction', 'id') reloading = all(( active_transaction, last_reload, last_reload == active_transaction, )) # only check for outstanding transactions if requested outstanding = False if pending: outstanding = active_transaction # return True if the instance has only if the instance has # finished provisioning and isn't currently reloading the OS. if all([instance.get('provisionDate'), not reloading, not outstanding]): return True now = time.time() if now >= until: return False time.sleep(min(delay, until - now))
def _update_with_like_args(self, args): """ Update arguments with options taken from a currently running VS. :param VSManager args: A VSManager :param dict args: CLI arguments """ if args['--like']: vsi = SoftLayer.VSManager(self.client) vs_id = helpers.resolve_id(vsi.resolve_ids, args.pop('--like'), 'VS') like_details = vsi.get_instance(vs_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'], } tag_refs = like_details.get('tagReferences', None) if tag_refs is not None and len(tag_refs) > 0: tags = ','.join([t['tag']['name'] for t in tag_refs]) like_args['--tag'] = tags # Handle mutually exclusive options like_image = utils.lookup(like_details, 'blockDeviceTemplateGroup', 'globalIdentifier') like_os = utils.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 VS options with the options passed in for key, value in like_args.items(): if args.get(key) in [None, False]: args[key] = value
def capture(self, instance_id, name, additional_disks=False, notes=None): """Capture one or all disks from a VS to a SoftLayer image. Parameters set to None will be ignored and not attempted to be updated. :param integer instance_id: the instance ID to edit :param string name: name assigned to the image :param bool additional_disks: set to true to include all additional attached storage devices :param string notes: notes about this particular image :returns: dictionary -- information about the capture transaction. Example:: name = "Testing Images" notes = "Some notes about this image" result = mgr.capture(instance_id=12345, name=name, notes=notes) """ vsi = self.client.call( 'Virtual_Guest', 'getObject', id=instance_id, mask="""id, blockDevices[id,device,mountType, diskImage[id,metadataFlag,type[keyName]]]""") disks_to_capture = [] for block_device in vsi['blockDevices']: # We never want metadata disks if utils.lookup(block_device, 'diskImage', 'metadataFlag'): continue # We never want swap devices type_name = utils.lookup(block_device, 'diskImage', 'type', 'keyName') if type_name == 'SWAP': continue # We never want CD images if block_device['mountType'] == 'CD': continue # Only use the first block device if we don't want additional disks if not additional_disks and str(block_device['device']) != '0': continue disks_to_capture.append(block_device) return self.guest.createArchiveTransaction( name, disks_to_capture, notes, id=instance_id)
def _get_virtual_bandwidth(env, start, end): call = env.client.call( 'Account', 'getVirtualGuests', iter=True, mask='id,hostname,metricTrackingObjectId,' 'virtualRack[id,bandwidthAllotmentTypeId]') types = [ {'keyName': 'PUBLICIN_NET_OCTET', 'name': 'publicIn_net_octet', 'summaryType': 'sum'}, {'keyName': 'PUBLICOUT_NET_OCTET', 'name': 'publicOut_net_octet', 'summaryType': 'sum'}, {'keyName': 'PRIVATEIN_NET_OCTET', 'name': 'privateIn_net_octet', 'summaryType': 'sum'}, {'keyName': 'PRIVATEOUT_NET_OCTET', 'name': 'privateOut_net_octet', 'summaryType': 'sum'}, ] with click.progressbar(list(call), label='Calculating for virtual', file=sys.stderr) as vms: for instance in vms: metric_tracking_id = utils.lookup(instance, 'metricTrackingObjectId') if metric_tracking_id is None: continue pool_name = None if utils.lookup(instance, 'virtualRack', 'bandwidthAllotmentTypeId') == 2: pool_name = utils.lookup(instance, 'virtualRack', 'id') yield { 'id': instance['id'], 'type': 'virtual', 'name': instance['hostname'], 'pool': pool_name, 'data': env.client.call( 'Metric_Tracking_Object', 'getSummaryData', start.strftime('%Y-%m-%d %H:%M:%S %Z'), end.strftime('%Y-%m-%d %H:%M:%S %Z'), types, 3600, id=metric_tracking_id, ), }
def _update_with_like_args(ctx, _, value): """Update arguments with options taken from a currently running VS.""" if value is None: return env = ctx.ensure_object(environment.Environment) vsi = SoftLayer.VSManager(env.client) vs_id = helpers.resolve_id(vsi.resolve_ids, value, 'VS') like_details = vsi.get_instance(vs_id) like_args = { 'hostname': like_details['hostname'], 'domain': like_details['domain'], 'hourly': like_details['hourlyBillingFlag'], 'datacenter': like_details['datacenter']['name'], 'network': like_details['networkComponents'][0]['maxSpeed'], 'userdata': like_details['userData'] or None, 'postinstall': like_details.get('postInstallScriptUri'), 'dedicated': like_details['dedicatedAccountHostOnlyFlag'], 'private': like_details['privateNetworkOnlyFlag'], 'placement_id': like_details.get('placementGroupId', None), } like_args['flavor'] = utils.lookup(like_details, 'billingItem', 'orderItem', 'preset', 'keyName') if not like_args['flavor']: like_args['cpu'] = like_details['maxCpu'] like_args['memory'] = '%smb' % like_details['maxMemory'] tag_refs = like_details.get('tagReferences', None) if tag_refs is not None and len(tag_refs) > 0: like_args['tag'] = [t['tag']['name'] for t in tag_refs] # Handle mutually exclusive options like_image = utils.lookup(like_details, 'blockDeviceTemplateGroup', 'globalIdentifier') like_os = utils.lookup(like_details, 'operatingSystem', 'softwareLicense', 'softwareDescription', 'referenceCode') if like_image: like_args['image'] = like_image elif like_os: like_args['os'] = like_os if ctx.default_map is None: ctx.default_map = {} ctx.default_map.update(like_args)
def basic_event_table(event): """Formats a basic event table""" table = formatting.Table(["Id", "Status", "Type", "Start", "End"], title=utils.clean_splitlines(event.get('subject'))) table.add_row([ event.get('id'), utils.lookup(event, 'statusCode', 'name'), utils.lookup(event, 'notificationOccurrenceEventType', 'keyName'), utils.clean_time(event.get('startDate')), utils.clean_time(event.get('endDate')) ]) return table
def do_POST(self): """Handle XML-RPC POSTs.""" try: length = int(self.headers['Content-Length']) data = self.rfile.read(length).decode('utf-8') args, method = utils.xmlrpc_client.loads(data) headers = args[0].get('headers', {}) # Form Request for the transport req = transports.Request() req.service = self.path.lstrip('/') req.method = method req.limit = utils.lookup(headers, 'resultLimit', 'limit') req.offset = utils.lookup(headers, 'resultLimit', 'offset') req.args = args[1:] req.filter = _item_by_key_postfix(headers, 'ObjectFilter') or None req.mask = _item_by_key_postfix(headers, 'ObjectMask').get('mask') req.identifier = _item_by_key_postfix(headers, 'InitParameters').get('id') req.transport_headers = dict(((k.lower(), v) for k, v in self.headers.items())) req.headers = headers # Get response response = self.server.transport(req) response_body = utils.xmlrpc_client.dumps((response,), allow_none=True, methodresponse=True) self.send_response(200) self.send_header("Content-type", "application/xml; charset=UTF-8") self.end_headers() try: self.wfile.write(response_body.encode('utf-8')) except UnicodeDecodeError: self.wfile.write(response_body) except SoftLayer.SoftLayerAPIError as ex: self.send_response(200) self.end_headers() response = utils.xmlrpc_client.Fault(ex.faultCode, str(ex.reason)) response_body = utils.xmlrpc_client.dumps(response, allow_none=True, methodresponse=True) self.wfile.write(response_body.encode('utf-8')) except Exception as ex: self.send_response(500) logging.exception("Error while handling request")
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
def _get_hardware_bandwidth(env, start, end): hw_call = env.client.call( 'Account', 'getHardware', iter=True, mask='id,hostname,metricTrackingObject.id,' 'virtualRack[id,bandwidthAllotmentTypeId]') types = [ {'keyName': 'PUBLICIN', 'name': 'publicIn', 'summaryType': 'counter'}, {'keyName': 'PUBLICOUT', 'name': 'publicOut', 'summaryType': 'counter'}, {'keyName': 'PRIVATEIN', 'name': 'privateIn', 'summaryType': 'counter'}, {'keyName': 'PRIVATEOUT', 'name': 'privateOut', 'summaryType': 'counter'}, ] with click.progressbar(list(hw_call), label='Calculating for hardware', file=sys.stderr) as hws: for instance in hws: if not utils.lookup(instance, 'metricTrackingObject', 'id'): continue pool_name = None if utils.lookup(instance, 'virtualRack', 'bandwidthAllotmentTypeId') == 2: pool_name = utils.lookup(instance, 'virtualRack', 'name') yield { 'id': instance['id'], 'type': 'hardware', 'name': instance['hostname'], 'pool': pool_name, 'data': env.client.call( 'Metric_Tracking_Object', 'getSummaryData', start.strftime('%Y-%m-%d %H:%M:%S %Z'), end.strftime('%Y-%m-%d %H:%M:%S %Z'), types, 3600, id=instance['metricTrackingObject']['id'], ), }
def cli(env, **args): """Order/create virtual servers.""" vsi = SoftLayer.VSManager(env.client) _validate_args(env, args) create_args = _parse_create_args(env.client, args) test = args.get('test', False) do_create = not (args.get('export') or test) if do_create: if not (env.skip_confirmations or formatting.confirm( "This action will incur charges on your account. Continue?")): raise exceptions.CLIAbort('Aborting virtual server order.') if args.get('export'): export_file = args.pop('export') template.export_to_template(export_file, args, exclude=['wait', 'test']) env.fout('Successfully exported options to a template file.') else: result = vsi.order_guest(create_args, test) output = _build_receipt_table(result, args.get('billing'), test) if do_create: env.fout(_build_guest_table(result)) env.fout(output) if args.get('wait'): virtual_guests = utils.lookup(result, 'orderDetails', 'virtualGuests') guest_id = virtual_guests[0]['id'] click.secho("Waiting for %s to finish provisioning..." % guest_id, fg='green') ready = vsi.wait_for_ready(guest_id, args.get('wait') or 1) if ready is False: env.out(env.fmt(output)) raise exceptions.CLIHalt(code=1)
def cli(env): """List iSCSI targets.""" iscsi_mgr = SoftLayer.ISCSIManager(env.client) iscsi_list = iscsi_mgr.list_iscsi() iscsi_list = [utils.NestedDict(n) for n in iscsi_list] table = formatting.Table([ 'id', 'datacenter', 'size', 'username', 'password', 'server' ]) for iscsi in iscsi_list: table.add_row([ iscsi['id'], utils.lookup(iscsi, 'serviceResource', 'datacenter', 'name') or formatting.blank(), formatting.FormattedItem(iscsi.get('capacityGb', formatting.blank()), "%dGB" % iscsi.get('capacityGb', 0)), iscsi.get('username', formatting.blank()), iscsi.get('password', formatting.blank()), iscsi.get('serviceResourceBackendIpAddress', formatting.blank())]) env.fout(table)
def cli(env): """List firewalls.""" mgr = SoftLayer.FirewallManager(env.client) table = formatting.Table(['firewall id', 'type', 'features', 'server/vlan id']) fwvlans = mgr.get_firewalls() dedicated_firewalls = [firewall for firewall in fwvlans if firewall['dedicatedFirewallFlag']] for vlan in dedicated_firewalls: features = [] if vlan['highAvailabilityFirewallFlag']: features.append('HA') if features: feature_list = formatting.listing(features, separator=',') else: feature_list = formatting.blank() table.add_row([ 'vlan:%s' % vlan['networkVlanFirewall']['id'], 'VLAN - dedicated', feature_list, vlan['id'] ]) shared_vlan = [firewall for firewall in fwvlans if not firewall['dedicatedFirewallFlag']] for vlan in shared_vlan: vs_firewalls = [guest for guest in vlan['firewallGuestNetworkComponents'] if has_firewall_component(guest)] for firewall in vs_firewalls: table.add_row([ 'vs:%s' % firewall['id'], 'Virtual Server - standard', '-', firewall['guestNetworkComponent']['guest']['id'] ]) server_firewalls = [server for server in vlan['firewallNetworkComponents'] if has_firewall_component(server)] for firewall in server_firewalls: table.add_row([ 'server:%s' % firewall['id'], 'Server - standard', '-', utils.lookup(firewall, 'networkComponent', 'downlinkComponent', 'hardwareId') ]) env.fout(table)
def cancel_block_volume(self, volume_id, reason='No longer needed', immediate=False): """Cancels the given block storage volume. :param integer volume_id: The volume ID :param string reason: The reason for cancellation :param boolean immediate_flag: Cancel immediately or on anniversary date """ block_volume = self.get_block_volume_details( volume_id, mask='mask[id,billingItem[id,hourlyFlag]]') if 'billingItem' not in block_volume: raise exceptions.SoftLayerError("Block Storage was already cancelled") billing_item_id = block_volume['billingItem']['id'] if utils.lookup(block_volume, 'billingItem', 'hourlyFlag'): immediate = True return self.client['Billing_Item'].cancelItem( immediate, True, reason, id=billing_item_id)
def cli(env, sortby, datacenter, number, name): """List VLANs.""" mgr = SoftLayer.NetworkManager(env.client) table = formatting.Table([ 'id', 'number', 'datacenter', 'name', 'IPs', 'hardware', 'vs', 'networking', 'firewall' ]) table.sortby = sortby vlans = mgr.list_vlans(datacenter=datacenter, vlan_number=number, name=name) for vlan in vlans: table.add_row([ vlan['id'], vlan['vlanNumber'], utils.lookup(vlan, 'primaryRouter', 'datacenter', 'name'), vlan.get('name') or formatting.blank(), vlan['totalPrimaryIpAddressCount'], len(vlan['hardware']), len(vlan['virtualGuests']), len(vlan['networkComponents']), 'Yes' if vlan['firewallInterfaces'] else 'No', ]) return table
def _get_bandwidth_price_id(items, hourly=True, no_public=False, location=None): """Choose a valid price id for bandwidth.""" # Prefer pay-for-use data transfer with hourly for item in items: capacity = float(item.get('capacity', 0)) # Hourly and private only do pay-as-you-go bandwidth if any([not utils.lookup(item, 'itemCategory', 'categoryCode') == 'bandwidth', (hourly or no_public) and capacity != 0.0, not (hourly or no_public) and capacity == 0.0]): continue for price in item['prices']: if not _matches_billing(price, hourly): continue if not _matches_location(price, location): continue return price['id'] raise SoftLayer.SoftLayerError( "Could not find valid price for bandwidth option")
def cli(env): """List NAS accounts.""" account = env.client['Account'] nas_accounts = account.getNasNetworkStorage( mask='eventCount,serviceResource[datacenter.name]') table = formatting.Table(['id', 'datacenter', 'size', 'username', 'password', 'server']) for nas_account in nas_accounts: table.add_row([ nas_account['id'], utils.lookup(nas_account, 'serviceResource', 'datacenter', 'name') or formatting.blank(), formatting.FormattedItem( nas_account.get('capacityGb', formatting.blank()), "%dGB" % nas_account.get('capacityGb', 0)), nas_account.get('username', formatting.blank()), nas_account.get('password', formatting.blank()), nas_account.get('serviceResourceBackendIpAddress', formatting.blank())]) return table
def row(self, data): """Return a formatted row for the given data.""" for column in self.column_funcs: if callable(column): yield column(data) else: yield utils.lookup(data, *column)
def cli(env, sortby, datacenter, number, name): """List VLANs.""" mgr = SoftLayer.NetworkManager(env.client) table = formatting.Table(["id", "number", "datacenter", "name", "IPs", "hardware", "vs", "networking", "firewall"]) table.sortby = sortby vlans = mgr.list_vlans(datacenter=datacenter, vlan_number=number, name=name) for vlan in vlans: table.add_row( [ vlan["id"], vlan["vlanNumber"], utils.lookup(vlan, "primaryRouter", "datacenter", "name"), vlan.get("name") or formatting.blank(), vlan["totalPrimaryIpAddressCount"], len(vlan["hardware"]), len(vlan["virtualGuests"]), len(vlan["networkComponents"]), "Yes" if vlan["firewallInterfaces"] else "No", ] ) env.fout(table)
def wait_for_ready(self, instance_id, limit=14400, delay=10, pending=False): """Determine if a Server is ready. A server is ready when no transactions are running on it. :param int instance_id: The instance ID with the pending transaction :param int limit: The maximum amount of seconds to wait. :param int delay: The number of seconds to sleep before checks. Defaults to 10. """ now = time.time() until = now + limit mask = "mask[id, lastOperatingSystemReload[id], activeTransaction, provisionDate]" instance = self.get_hardware(instance_id, mask=mask) while now <= until: if utils.is_ready(instance, pending): return True transaction = utils.lookup(instance, 'activeTransaction', 'transactionStatus', 'friendlyName') snooze = min(delay, until - now) LOGGER.info("%s - %d not ready. Auto retry in %ds", transaction, instance_id, snooze) time.sleep(snooze) instance = self.get_hardware(instance_id, mask=mask) now = time.time() LOGGER.info("Waiting for %d expired.", instance_id) return False
def execute(self, args): mgr = NetworkManager(self.client) table = Table([ 'id', 'identifier', 'type', 'datacenter', 'vlan id', 'IPs', 'hardware', 'ccis', ]) table.sortby = args.get('--sortby') or 'id' version = 0 if args.get('--v4'): version = 4 elif args.get('--v6'): version = 6 subnets = mgr.list_subnets( datacenter=args.get('--datacenter'), version=version, identifier=args.get('--identifier'), subnet_type=args.get('--type'), ) for subnet in subnets: table.add_row([ subnet['id'], '%s/%s' % (subnet['networkIdentifier'], str(subnet['cidr'])), subnet.get('subnetType', blank()), lookup(subnet, 'datacenter', 'name',) or blank(), subnet['networkVlanId'], subnet['ipAddressCount'], len(subnet['hardware']), len(subnet['virtualGuests']), ]) return table
def _validate_dupl_performance_iops(origin_volume, duplicate_iops, duplicate_size): if not isinstance(utils.lookup(origin_volume, 'provisionedIops'), str): raise exceptions.SoftLayerError( "Cannot find origin volume's provisioned IOPS") if duplicate_iops is None: duplicate_iops = int(origin_volume['provisionedIops']) else: origin_iops_per_gb = float(origin_volume['provisionedIops'])\ / float(origin_volume['capacityGb']) duplicate_iops_per_gb = float(duplicate_iops) / float(duplicate_size) if origin_iops_per_gb < 0.3 and duplicate_iops_per_gb >= 0.3: raise exceptions.SoftLayerError( "Origin volume performance is < 0.3 IOPS/GB, " "duplicate volume performance must also be < 0.3 " "IOPS/GB. %s IOPS/GB (%s/%s) requested." % (duplicate_iops_per_gb, duplicate_iops, duplicate_size)) elif origin_iops_per_gb >= 0.3 and duplicate_iops_per_gb < 0.3: raise exceptions.SoftLayerError( "Origin volume performance is >= 0.3 IOPS/GB, " "duplicate volume performance must also be >= 0.3 " "IOPS/GB. %s IOPS/GB (%s/%s) requested." % (duplicate_iops_per_gb, duplicate_iops, duplicate_size)) return duplicate_iops
def cli(env, quote): """View a quote""" manager = ordering.OrderingManager(env.client) result = manager.get_quote_details(quote) package = result['order']['items'][0]['package'] title = "{} - Package: {}, Id {}".format(result.get('name'), package['keyName'], package['id']) table = formatting.Table([ 'Category', 'Description', 'Quantity', 'Recurring', 'One Time' ], title=title) table.align['Category'] = 'l' table.align['Description'] = 'l' items = lookup(result, 'order', 'items') for item in items: table.add_row([ item.get('categoryCode'), item.get('description'), item.get('quantity'), item.get('recurringFee'), item.get('oneTimeFee') ]) env.fout(table)
def cli(env, sortby, datacenter, number, name, limit): """List VLANs.""" mgr = SoftLayer.NetworkManager(env.client) table = formatting.Table(COLUMNS) table.sortby = sortby vlans = mgr.list_vlans(datacenter=datacenter, vlan_number=number, name=name, limit=limit) for vlan in vlans: table.add_row([ vlan['id'], vlan['vlanNumber'], vlan.get('name') or formatting.blank(), 'Yes' if vlan['firewallInterfaces'] else 'No', utils.lookup(vlan, 'primaryRouter', 'datacenter', 'name'), vlan['hardwareCount'], vlan['virtualGuestCount'], vlan['totalPrimaryIpAddressCount'], ]) env.fout(table)
def cli(env, identifier): """Get details for an image.""" image_mgr = SoftLayer.ImageManager(env.client) image_id = helpers.resolve_id(image_mgr.resolve_ids, identifier, 'image') image = image_mgr.get_image(image_id, mask=image_mod.DETAIL_MASK) disk_space = 0 datacenters = [] for child in image.get('children'): disk_space = int(child.get('blockDevicesDiskSpaceTotal', 0)) if child.get('datacenter'): datacenters.append(utils.lookup(child, 'datacenter', 'name')) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' table.add_row(['id', image['id']]) table.add_row(['global_identifier', image.get('globalIdentifier', formatting.blank())]) table.add_row(['name', image['name'].strip()]) table.add_row(['status', formatting.FormattedItem( utils.lookup(image, 'status', 'keyname'), utils.lookup(image, 'status', 'name'), )]) table.add_row([ 'active_transaction', formatting.transaction_status(image.get('transaction')), ]) table.add_row(['account', image.get('accountId', formatting.blank())]) table.add_row(['visibility', image_mod.PUBLIC_TYPE if image['publicFlag'] else image_mod.PRIVATE_TYPE]) table.add_row(['type', formatting.FormattedItem( utils.lookup(image, 'imageType', 'keyName'), utils.lookup(image, 'imageType', 'name'), )]) table.add_row(['flex', image.get('flexImageFlag')]) table.add_row(['note', image.get('note')]) table.add_row(['created', image.get('createDate')]) table.add_row(['disk_space', formatting.b_to_gb(disk_space)]) table.add_row(['datacenters', formatting.listing(sorted(datacenters), separator=',')]) env.fout(table)
def add_subnet(self, subnet_type, quantity=None, vlan_id=None, version=4, test_order=False): """Orders a new subnet :param str subnet_type: Type of subnet to add: private, public, global :param int quantity: Number of IPs in the subnet :param int vlan_id: VLAN id for the subnet to be placed into :param int version: 4 for IPv4, 6 for IPv6 :param bool test_order: If true, this will only verify the order. """ package = self.client['Product_Package'] category = 'sov_sec_ip_addresses_priv' desc = '' if version == 4: if subnet_type == 'global': quantity = 0 category = 'global_ipv4' elif subnet_type == 'public': category = 'sov_sec_ip_addresses_pub' else: category = 'static_ipv6_addresses' if subnet_type == 'global': quantity = 0 category = 'global_ipv6' desc = 'Global' elif subnet_type == 'public': desc = 'Portable' # In the API, every non-server item is contained within package ID 0. # This means that we need to get all of the items and loop through them # looking for the items we need based upon the category, quantity, and # item description. price_id = None quantity_str = str(quantity) for item in package.getItems(id=0, mask='itemCategory'): category_code = utils.lookup(item, 'itemCategory', 'categoryCode') if all([category_code == category, item.get('capacity') == quantity_str, version == 4 or (version == 6 and desc in item['description'])]): price_id = item['prices'][0]['id'] break order = { 'packageId': 0, 'prices': [{'id': price_id}], 'quantity': 1, # This is necessary in order for the XML-RPC endpoint to select the # correct order container 'complexType': 'SoftLayer_Container_Product_Order_Network_Subnet', } if subnet_type != 'global': order['endPointVlanId'] = vlan_id if test_order: return self.client['Product_Order'].verifyOrder(order) else: return self.client['Product_Order'].placeOrder(order)
def _get_os_price_id(items, os): """Returns the price id matching.""" for item in items: if any([not utils.lookup(item, 'itemCategory', 'categoryCode') == 'os', not utils.lookup(item, 'softwareDescription', 'referenceCode') == os]): continue for price in item['prices']: return price['id'] raise SoftLayer.SoftLayerError("Could not find valid price for os: '%s'" % os)
def _build_guest_table(result): table = formatting.Table(['ID', 'FQDN', 'guid', 'Order Date']) table.align['name'] = 'r' table.align['value'] = 'l' virtual_guests = utils.lookup(result, 'orderDetails', 'virtualGuests') for guest in virtual_guests: table.add_row([guest['id'], guest['fullyQualifiedDomainName'], guest['globalIdentifier'], result['orderDate']]) return table
def active_txn(item): """Returns a FormattedItem describing the active transaction on a object. If no active transaction is running, returns a blank FormattedItem. :param item: An object capable of having an active transaction """ return transaction_status(utils.lookup(item, 'activeTransaction'))
def wait_for_ready(self, instance_id, limit, delay=10, pending=False): """Determine if a VS is ready and available. In some cases though, that can mean that no transactions are running. The default arguments imply a VS is operational and ready for use by having network connectivity and remote access is available. Setting ``pending=True`` will ensure future API calls against this instance will not error due to pending transactions such as OS Reloads and cancellations. :param int instance_id: The instance ID with the pending transaction :param int limit: The maximum amount of time to wait. :param int delay: The number of seconds to sleep before checks. Defaults to 10. :param bool pending: Wait for pending transactions not related to provisioning or reloads such as monitoring. Example:: # Will return once vsi 12345 is ready, or after 10 checks ready = mgr.wait_for_ready(12345, 10) """ until = time.time() + limit for new_instance in itertools.repeat(instance_id): mask = """id, lastOperatingSystemReload.id, activeTransaction.id,provisionDate""" try: instance = self.get_instance(new_instance, mask=mask) last_reload = utils.lookup(instance, 'lastOperatingSystemReload', 'id') active_transaction = utils.lookup(instance, 'activeTransaction', 'id') reloading = all(( active_transaction, last_reload, last_reload == active_transaction, )) # only check for outstanding transactions if requested outstanding = False if pending: outstanding = active_transaction # return True if the instance has finished provisioning # and isn't currently reloading the OS. if all([ instance.get('provisionDate'), not reloading, not outstanding ]): return True LOGGER.info("%s not ready.", str(instance_id)) except exceptions.SoftLayerAPIError as exception: delay = (delay * 2) + random.randint(0, 9) LOGGER.info('Exception: %s', str(exception)) now = time.time() if now >= until: return False LOGGER.info('Auto retry in %s seconds', str(min(delay, until - now))) time.sleep(min(delay, until - now)) return False
def cli(env): """List firewalls.""" mgr = SoftLayer.FirewallManager(env.client) table = formatting.Table( ['firewall id', 'type', 'features', 'server/vlan id'], title='Single Server Firewalls') fwvlans = mgr.get_firewalls() dedicated_firewalls = [ firewall for firewall in fwvlans if firewall['dedicatedFirewallFlag'] ] for vlan in dedicated_firewalls: features = [] if vlan['highAvailabilityFirewallFlag']: features.append('HA') if features: feature_list = formatting.listing(features, separator=',') else: feature_list = formatting.blank() table.add_row([ 'vlan:%s' % vlan['networkVlanFirewall']['id'], 'VLAN - dedicated', feature_list, vlan['id'] ]) shared_vlan = [ firewall for firewall in fwvlans if not firewall['dedicatedFirewallFlag'] ] for vlan in shared_vlan: vs_firewalls = [ guest for guest in vlan['firewallGuestNetworkComponents'] if has_firewall_component(guest) ] for firewall in vs_firewalls: table.add_row([ 'vs:%s' % firewall['id'], 'Virtual Server - standard', '-', firewall['guestNetworkComponent']['guest']['id'] ]) server_firewalls = [ server for server in vlan['firewallNetworkComponents'] if has_firewall_component(server) ] for firewall in server_firewalls: table.add_row([ 'server:%s' % firewall['id'], 'Server - standard', '-', utils.lookup(firewall, 'networkComponent', 'downlinkComponent', 'hardwareId') ]) table_gatewalls = formatting.Table([ 'Id', 'firewall', 'type', 'Hostname', 'Location', 'Public Ip', 'Private Ip', 'Associated vlan', 'status' ], title='Multi Vlan Firewall') fw_gatewwalls = mgr.get_firewalls_gatewalls() for gatewalls in fw_gatewwalls: table_gatewalls.add_row([ gatewalls['networkFirewall']['id'], gatewalls.get('name'), gatewalls['networkFirewall']['firewallType'], gatewalls['members'][0]['hardware']['hostname'], gatewalls['networkFirewall']['datacenter']['name'], gatewalls['publicIpAddress']['ipAddress'], gatewalls['privateIpAddress']['ipAddress'], len(gatewalls['insideVlans']), gatewalls['status']['keyName'] ]) env.fout(table) env.fout(table_gatewalls)
def cli(env, volume_id): """Display details for a specified volume.""" file_manager = SoftLayer.FileStorageManager(env.client) file_volume_id = helpers.resolve_id(file_manager.resolve_ids, volume_id, 'File Storage') file_volume = file_manager.get_file_volume_details(file_volume_id) file_volume = utils.NestedDict(file_volume) table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' table.align['Value'] = 'l' storage_type = file_volume['storageType']['keyName'].split('_').pop(0) table.add_row(['ID', file_volume['id']]) table.add_row(['Username', file_volume['username']]) table.add_row(['Type', storage_type]) table.add_row(['Capacity (GB)', "%iGB" % file_volume['capacityGb']]) used_space = int(file_volume['bytesUsed']) \ if file_volume['bytesUsed'] else 0 if used_space < (1 << 10): table.add_row(['Used Space', "%dB" % used_space]) elif used_space < (1 << 20): table.add_row(['Used Space', "%dKB" % (used_space / (1 << 10))]) elif used_space < (1 << 30): table.add_row(['Used Space', "%dMB" % (used_space / (1 << 20))]) else: table.add_row(['Used Space', "%dGB" % (used_space / (1 << 30))]) if file_volume.get('provisionedIops'): table.add_row(['IOPs', float(file_volume['provisionedIops'])]) if file_volume.get('storageTierLevel'): table.add_row([ 'Endurance Tier', file_volume['storageTierLevel'], ]) table.add_row([ 'Data Center', file_volume['serviceResource']['datacenter']['name'], ]) table.add_row([ 'Target IP', file_volume['serviceResourceBackendIpAddress'], ]) if file_volume['fileNetworkMountAddress']: table.add_row([ 'Mount Address', file_volume['fileNetworkMountAddress'], ]) if file_volume['snapshotCapacityGb']: table.add_row([ 'Snapshot Capacity (GB)', file_volume['snapshotCapacityGb'], ]) if 'snapshotSizeBytes' in file_volume['parentVolume']: table.add_row([ 'Snapshot Used (Bytes)', file_volume['parentVolume']['snapshotSizeBytes'], ]) table.add_row([ '# of Active Transactions', "%i" % file_volume['activeTransactionCount'] ]) if file_volume['activeTransactions']: for trans in file_volume['activeTransactions']: if 'transactionStatus' in trans and 'friendlyName' in trans[ 'transactionStatus']: table.add_row([ 'Ongoing Transaction', trans['transactionStatus']['friendlyName'] ]) table.add_row([ 'Replicant Count', "%u" % file_volume.get('replicationPartnerCount', 0) ]) if file_volume['replicationPartnerCount'] > 0: # This if/else temporarily handles a bug in which the SL API # returns a string or object for 'replicationStatus'; it seems that # the type is string for File volumes and object for Block volumes if 'message' in file_volume['replicationStatus']: table.add_row([ 'Replication Status', "%s" % file_volume['replicationStatus']['message'] ]) else: table.add_row([ 'Replication Status', "%s" % file_volume['replicationStatus'] ]) replicant_list = [] for replicant in file_volume['replicationPartners']: replicant_table = formatting.Table( ['Replicant ID', replicant['id']]) replicant_table.add_row( ['Volume Name', utils.lookup(replicant, 'username')]) replicant_table.add_row([ 'Target IP', utils.lookup(replicant, 'serviceResourceBackendIpAddress') ]) replicant_table.add_row([ 'Data Center', utils.lookup(replicant, 'serviceResource', 'datacenter', 'name') ]) replicant_table.add_row([ 'Schedule', utils.lookup(replicant, 'replicationSchedule', 'type', 'keyname') ]) replicant_list.append(replicant_table) table.add_row(['Replicant Volumes', replicant_list]) if file_volume.get('originalVolumeSize'): original_volume_info = formatting.Table(['Property', 'Value']) original_volume_info.add_row( ['Original Volume Size', file_volume['originalVolumeSize']]) if file_volume.get('originalVolumeName'): original_volume_info.add_row( ['Original Volume Name', file_volume['originalVolumeName']]) if file_volume.get('originalSnapshotName'): original_volume_info.add_row([ 'Original Snapshot Name', file_volume['originalSnapshotName'] ]) table.add_row(['Original Volume Properties', original_volume_info]) notes = '{}'.format(file_volume.get('notes', '')) table.add_row(['Notes', notes]) env.fout(table)
def location_sort(location): """Quick function that just returns the datacenter longName for sorting""" return utils.lookup(location, 'datacenter', 'longName')
def execute(self, args): vsi = SoftLayer.VSManager(self.client) table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' table.align['Value'] = 'l' vs_id = helpers.resolve_id(vsi.resolve_ids, args.get('<identifier>'), 'VS') result = vsi.get_instance(vs_id) result = utils.NestedDict(result) table.add_row(['id', result['id']]) table.add_row(['hostname', result['fullyQualifiedDomainName']]) table.add_row([ 'status', formatting.FormattedItem( result['status']['keyName'] or formatting.blank(), result['status']['name'] or formatting.blank()) ]) table.add_row(['active_transaction', formatting.active_txn(result)]) table.add_row([ 'state', formatting.FormattedItem( utils.lookup(result, 'powerState', 'keyName'), utils.lookup(result, 'powerState', 'name'), ) ]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {} table.add_row([ 'os', formatting.FormattedItem( operating_system.get('version') or formatting.blank(), operating_system.get('name') or formatting.blank()) ]) table.add_row([ 'os_version', operating_system.get('version') or formatting.blank() ]) table.add_row(['cores', result['maxCpu']]) table.add_row(['memory', formatting.mb_to_gb(result['maxMemory'])]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row(['private_only', result['privateNetworkOnlyFlag']]) table.add_row(['private_cpu', result['dedicatedAccountHostOnlyFlag']]) table.add_row(['created', result['createDate']]) table.add_row(['modified', result['modifyDate']]) table.add_row([ 'owner', formatting.FormattedItem( utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') or formatting.blank(), ) ]) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if args.get('--price'): table.add_row( ['price rate', result['billingItem']['recurringFee']]) if args.get('--passwords'): pass_table = formatting.Table(['username', 'password']) for item in result['operatingSystem']['passwords']: pass_table.add_row([item['username'], item['password']]) table.add_row(['users', pass_table]) tag_row = [] for tag in result['tagReferences']: tag_row.append(tag['tag']['name']) if tag_row: table.add_row(['tags', formatting.listing(tag_row, separator=',')]) # Test to see if this actually has a primary (public) ip address if result['primaryIpAddress']: ptr_domains = ( self.client['Virtual_Guest'].getReverseDomainRecords(id=vs_id)) for ptr_domain in ptr_domains: for ptr in ptr_domain['resourceRecords']: table.add_row(['ptr', ptr['data']]) return table
def cli(env, identifier, passwords, price): """Get details for a hardware device.""" hardware = SoftLayer.HardwareManager(env.client) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware') result = hardware.get_hardware(hardware_id) result = utils.NestedDict(result) operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {} memory = formatting.gb(result.get('memoryCapacity', 0)) owner = None if utils.lookup(result, 'billingItem') != []: owner = utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') table.add_row(['id', result['id']]) table.add_row(['guid', result['globalIdentifier'] or formatting.blank()]) table.add_row(['hostname', result['hostname']]) table.add_row(['domain', result['domain']]) table.add_row(['fqdn', result['fullyQualifiedDomainName']]) table.add_row(['status', result['hardwareStatus']['status']]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) table.add_row(['cores', result['processorPhysicalCoreAmount']]) table.add_row(['memory', memory]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row([ 'ipmi_ip', result['networkManagementIpAddress'] or formatting.blank() ]) table.add_row(['os', operating_system.get('name') or formatting.blank()]) table.add_row( ['os_version', operating_system.get('version') or formatting.blank()]) table.add_row(['created', result['provisionDate'] or formatting.blank()]) table.add_row(['owner', owner or formatting.blank()]) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if price: total_price = utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount') or 0 price_table = formatting.Table(['Item', 'Recurring Price']) price_table.add_row(['Total', total_price]) for item in utils.lookup(result, 'billingItem', 'children') or []: price_table.add_row( [item['description'], item['nextInvoiceTotalRecurringAmount']]) table.add_row(['prices', price_table]) if passwords: pass_table = formatting.Table(['username', 'password']) for item in result['operatingSystem']['passwords']: pass_table.add_row([item['username'], item['password']]) table.add_row(['users', pass_table]) pass_table = formatting.Table(['ipmi_username', 'password']) for item in result['remoteManagementAccounts']: pass_table.add_row([item['username'], item['password']]) table.add_row(['remote users', pass_table]) table.add_row(['tags', formatting.tags(result['tagReferences'])]) env.fout(table)
def cli(env, identifier, no_vs, no_hardware): """Get details about a VLAN.""" mgr = SoftLayer.NetworkManager(env.client) vlan_id = helpers.resolve_id(mgr.resolve_vlan_ids, identifier, 'VLAN') vlan = mgr.get_vlan(vlan_id) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' table.add_row(['id', vlan.get('id')]) table.add_row(['number', vlan.get('vlanNumber')]) table.add_row([ 'datacenter', utils.lookup(vlan, 'primaryRouter', 'datacenter', 'longName') ]) table.add_row([ 'primary_router', utils.lookup(vlan, 'primaryRouter', 'fullyQualifiedDomainName') ]) table.add_row(['Gateway/Firewall', get_gateway_firewall(vlan)]) subnets = [] for subnet in vlan.get('subnets', []): subnet_table = formatting.KeyValueTable(['name', 'value']) subnet_table.align['name'] = 'r' subnet_table.align['value'] = 'l' subnet_table.add_row(['id', subnet.get('id')]) subnet_table.add_row(['identifier', subnet.get('networkIdentifier')]) subnet_table.add_row(['netmask', subnet.get('netmask')]) subnet_table.add_row( ['gateway', subnet.get('gateway', formatting.blank())]) subnet_table.add_row(['type', subnet.get('subnetType')]) subnet_table.add_row( ['usable ips', subnet.get('usableIpAddressCount')]) subnets.append(subnet_table) table.add_row(['subnets', subnets]) server_columns = ['hostname', 'domain', 'public_ip', 'private_ip'] if not no_vs: if vlan.get('virtualGuests'): vs_table = formatting.KeyValueTable(server_columns) for vsi in vlan['virtualGuests']: vs_table.add_row([ vsi.get('hostname'), vsi.get('domain'), vsi.get('primaryIpAddress'), vsi.get('primaryBackendIpAddress') ]) table.add_row(['vs', vs_table]) else: table.add_row(['vs', 'none']) if not no_hardware: if vlan.get('hardware'): hw_table = formatting.Table(server_columns) for hardware in vlan['hardware']: hw_table.add_row([ hardware.get('hostname'), hardware.get('domain'), hardware.get('primaryIpAddress'), hardware.get('primaryBackendIpAddress') ]) table.add_row(['hardware', hw_table]) else: table.add_row(['hardware', 'none']) env.fout(table)
def _get_virtual_bandwidth(env, start, end): call = env.client.call('Account', 'getVirtualGuests', iter=True, mask='id,hostname,metricTrackingObjectId,' 'virtualRack[id,bandwidthAllotmentTypeId]') types = [ { 'keyName': 'PUBLICIN_NET_OCTET', 'name': 'publicIn_net_octet', 'summaryType': 'sum' }, { 'keyName': 'PUBLICOUT_NET_OCTET', 'name': 'publicOut_net_octet', 'summaryType': 'sum' }, { 'keyName': 'PRIVATEIN_NET_OCTET', 'name': 'privateIn_net_octet', 'summaryType': 'sum' }, { 'keyName': 'PRIVATEOUT_NET_OCTET', 'name': 'privateOut_net_octet', 'summaryType': 'sum' }, ] with click.progressbar(list(call), label='Calculating for virtual', file=sys.stderr) as vms: for instance in vms: metric_tracking_id = utils.lookup(instance, 'metricTrackingObjectId') if metric_tracking_id is None: continue pool_name = None if utils.lookup(instance, 'virtualRack', 'bandwidthAllotmentTypeId') == 2: pool_name = utils.lookup(instance, 'virtualRack', 'id') yield { 'id': instance['id'], 'type': 'virtual', 'name': instance['hostname'], 'pool': pool_name, 'data': env.client.call( 'Metric_Tracking_Object', 'getSummaryData', start.strftime('%Y-%m-%d %H:%M:%S %Z'), end.strftime('%Y-%m-%d %H:%M:%S %Z'), types, 3600, id=metric_tracking_id, ), }
def cli(env, identifier, passwords=False, price=False): """Get details for a virtual server.""" vsi = SoftLayer.VSManager(env.client) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS') result = vsi.get_instance(vs_id) result = utils.NestedDict(result) table.add_row(['id', result['id']]) table.add_row(['guid', result['globalIdentifier']]) table.add_row(['hostname', result['hostname']]) table.add_row(['domain', result['domain']]) table.add_row(['fqdn', result['fullyQualifiedDomainName']]) table.add_row([ 'status', formatting.FormattedItem(result['status']['keyName'], result['status']['name']) ]) table.add_row([ 'state', formatting.FormattedItem( utils.lookup(result, 'powerState', 'keyName'), utils.lookup(result, 'powerState', 'name'), ) ]) table.add_row(['active_transaction', formatting.active_txn(result)]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) _cli_helper_dedicated_host(env, result, table) operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {} table.add_row(['os', operating_system.get('name', '-')]) table.add_row(['os_version', operating_system.get('version', '-')]) table.add_row(['cores', result['maxCpu']]) table.add_row(['memory', formatting.mb_to_gb(result['maxMemory'])]) table.add_row(['public_ip', result.get('primaryIpAddress', '-')]) table.add_row(['private_ip', result.get('primaryBackendIpAddress', '-')]) table.add_row(['private_only', result['privateNetworkOnlyFlag']]) table.add_row(['private_cpu', result['dedicatedAccountHostOnlyFlag']]) table.add_row(['transient', result.get('transientGuestFlag', False)]) table.add_row(['created', result['createDate']]) table.add_row(['modified', result['modifyDate']]) table.add_row(_get_owner_row(result)) table.add_row(_get_vlan_table(result)) bandwidth = vsi.get_bandwidth_allocation(vs_id) table.add_row(['Bandwidth', _bw_table(bandwidth)]) security_table = _get_security_table(result) if security_table is not None: table.add_row(['security_groups', security_table]) table.add_row(['notes', result.get('notes', '-')]) if price: total_price = utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount') or 0 total_price += sum( p['nextInvoiceTotalRecurringAmount'] for p in utils.lookup(result, 'billingItem', 'children') or []) table.add_row(['price_rate', total_price]) if passwords: pass_table = formatting.Table(['software', 'username', 'password']) for component in result['softwareComponents']: for item in component['passwords']: pass_table.add_row([ utils.lookup(component, 'softwareLicense', 'softwareDescription', 'name'), item['username'], item['password'], ]) table.add_row(['users', pass_table]) table.add_row(['tags', formatting.tags(result['tagReferences'])]) # Test to see if this actually has a primary (public) ip address try: if not result['privateNetworkOnlyFlag']: ptr_domains = env.client.call( 'Virtual_Guest', 'getReverseDomainRecords', id=vs_id, ) for ptr_domain in ptr_domains: for ptr in ptr_domain['resourceRecords']: table.add_row(['ptr', ptr['data']]) except SoftLayer.SoftLayerAPIError: pass env.fout(table)
def execute(self, args): hardware = SoftLayer.HardwareManager(self.client) table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' table.align['Value'] = 'l' hardware_id = helpers.resolve_id(hardware.resolve_ids, args.get('<identifier>'), 'hardware') result = hardware.get_hardware(hardware_id) result = utils.NestedDict(result) table.add_row(['id', result['id']]) table.add_row(['hostname', result['fullyQualifiedDomainName']]) table.add_row(['status', result['hardwareStatus']['status']]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) table.add_row(['cores', result['processorPhysicalCoreAmount']]) table.add_row(['memory', formatting.gb(result['memoryCapacity'])]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row([ 'ipmi_ip', result['networkManagementIpAddress'] or formatting.blank() ]) table.add_row([ 'os', formatting.FormattedItem( result['operatingSystem']['softwareLicense'] ['softwareDescription']['referenceCode'] or formatting.blank(), result['operatingSystem']['softwareLicense'] ['softwareDescription']['name'] or formatting.blank()) ]) table.add_row( ['created', result['provisionDate'] or formatting.blank()]) table.add_row([ 'owner', formatting.FormattedItem( utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') or formatting.blank()) ]) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if args.get('--price'): table.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'])) table.add_row(['users', formatting.listing(user_strs)]) tag_row = [] for tag in result['tagReferences']: tag_row.append(tag['tag']['name']) if tag_row: table.add_row(['tags', formatting.listing(tag_row, separator=',')]) # Test to see if this actually has a primary (public) ip address try: if not result['privateNetworkOnlyFlag']: ptr_domains = ( self.client['Hardware_Server'].getReverseDomainRecords( id=hardware_id)) for ptr_domain in ptr_domains: for ptr in ptr_domain['resourceRecords']: table.add_row(['ptr', ptr['data']]) except SoftLayer.SoftLayerAPIError: pass return table
def cancel_hardware(self, hardware_id, reason='unneeded', comment='', immediate=False): """Cancels the specified dedicated server. Example:: # Cancels hardware id 1234 result = mgr.cancel_hardware(hardware_id=1234) :param int hardware_id: The ID of the hardware to be cancelled. :param string reason: The reason code for the cancellation. This should come from :func:`get_cancellation_reasons`. :param string comment: An optional comment to include with the cancellation. :param bool immediate: If set to True, will automatically update the cancelation ticket to request the resource be reclaimed asap. This request still has to be reviewed by a human :returns: True on success or an exception """ # Get cancel reason reasons = self.get_cancellation_reasons() cancel_reason = reasons.get(reason, reasons['unneeded']) ticket_mgr = SoftLayer.TicketManager(self.client) mask = 'mask[id, hourlyBillingFlag, billingItem[id], openCancellationTicket[id], activeTransaction]' hw_billing = self.get_hardware(hardware_id, mask=mask) if 'activeTransaction' in hw_billing: raise SoftLayer.SoftLayerError( "Unable to cancel hardware with running transaction") if 'billingItem' not in hw_billing: if utils.lookup(hw_billing, 'openCancellationTicket', 'id'): raise SoftLayer.SoftLayerError( "Ticket #%s already exists for this server" % hw_billing['openCancellationTicket']['id']) raise SoftLayer.SoftLayerError( "Cannot locate billing for the server. " "The server may already be cancelled.") billing_id = hw_billing['billingItem']['id'] if immediate and not hw_billing['hourlyBillingFlag']: LOGGER.warning( "Immediate cancellation of monthly servers is not guaranteed." "Please check the cancellation ticket for updates.") result = self.client.call('Billing_Item', 'cancelItem', False, False, cancel_reason, comment, id=billing_id) hw_billing = self.get_hardware(hardware_id, mask=mask) ticket_number = hw_billing['openCancellationTicket']['id'] cancel_message = "Please reclaim this server ASAP, it is no longer needed. Thankyou." ticket_mgr.update_ticket(ticket_number, cancel_message) LOGGER.info( "Cancelation ticket #%s has been updated requesting immediate reclaim", ticket_number) else: result = self.client.call('Billing_Item', 'cancelItem', immediate, False, cancel_reason, comment, id=billing_id) hw_billing = self.get_hardware(hardware_id, mask=mask) ticket_number = hw_billing['openCancellationTicket']['id'] LOGGER.info("Cancelation ticket #%s has been created", ticket_number) return result
def prepare_duplicate_order_object(manager, origin_volume, iops, tier, duplicate_size, duplicate_snapshot_size, volume_type, hourly_billing_flag=False): """Prepare the duplicate order to submit to SoftLayer_Product::placeOrder() :param manager: The File or Block manager calling this function :param origin_volume: The origin volume which is being duplicated :param iops: The IOPS for the duplicate volume (performance) :param tier: The tier level for the duplicate volume (endurance) :param duplicate_size: The requested size for the duplicate volume :param duplicate_snapshot_size: The size for the duplicate snapshot space :param volume_type: The type of the origin volume ('file' or 'block') :param hourly_billing_flag: Billing type, monthly (False) or hourly (True) :return: Returns the order object to be passed to the placeOrder() method of the Product_Order service """ # Verify that the origin volume has not been cancelled if 'billingItem' not in origin_volume: raise exceptions.SoftLayerError( "The origin volume has been cancelled; " "unable to order duplicate volume") # Verify that the origin volume has snapshot space (needed for duplication) if isinstance(utils.lookup(origin_volume, 'snapshotCapacityGb'), str): origin_snapshot_size = int(origin_volume['snapshotCapacityGb']) else: raise exceptions.SoftLayerError( "Snapshot space not found for the origin volume. " "Origin snapshot space is needed for duplication.") # Obtain the datacenter location ID for the duplicate if isinstance(utils.lookup(origin_volume, 'billingItem', 'location', 'id'), int): location_id = origin_volume['billingItem']['location']['id'] else: raise exceptions.SoftLayerError( "Cannot find origin volume's location") # Ensure the origin volume is STaaS v2 or higher # and supports Encryption at Rest if not _staas_version_is_v2_or_above(origin_volume): raise exceptions.SoftLayerError( "This volume cannot be duplicated since it " "does not support Encryption at Rest.") # If no specific snapshot space was requested for the duplicate, # use the origin snapshot space size if duplicate_snapshot_size is None: duplicate_snapshot_size = origin_snapshot_size # Use the origin volume size if no size was specified for the duplicate if duplicate_size is None: duplicate_size = origin_volume['capacityGb'] # Get the appropriate package for the order # ('storage_as_a_service' is currently used for duplicate volumes) package = get_package(manager, 'storage_as_a_service') # Determine the IOPS or tier level for the duplicate volume, along with # the type and prices for the order origin_storage_type = origin_volume['storageType']['keyName'] if 'PERFORMANCE' in origin_storage_type: volume_is_performance = True if iops is None: iops = int(origin_volume.get('provisionedIops', 0)) if iops <= 0: raise exceptions.SoftLayerError("Cannot find origin volume's provisioned IOPS") # Set up the price array for the order prices = [ find_price_by_category(package, 'storage_as_a_service'), find_price_by_category(package, 'storage_' + volume_type), find_saas_perform_space_price(package, duplicate_size), find_saas_perform_iops_price(package, duplicate_size, iops), ] # Add the price code for snapshot space as well, unless 0 GB was given if duplicate_snapshot_size > 0: prices.append(find_saas_snapshot_space_price( package, duplicate_snapshot_size, iops=iops)) elif 'ENDURANCE' in origin_storage_type: volume_is_performance = False if tier is None: tier = find_endurance_tier_iops_per_gb(origin_volume) # Set up the price array for the order prices = [ find_price_by_category(package, 'storage_as_a_service'), find_price_by_category(package, 'storage_' + volume_type), find_saas_endurance_space_price(package, duplicate_size, tier), find_saas_endurance_tier_price(package, tier), ] # Add the price code for snapshot space as well, unless 0 GB was given if duplicate_snapshot_size > 0: prices.append(find_saas_snapshot_space_price( package, duplicate_snapshot_size, tier=tier)) else: raise exceptions.SoftLayerError( "Origin volume does not have a valid storage type " "(with an appropriate keyName to indicate the " "volume is a PERFORMANCE or an ENDURANCE volume)") duplicate_order = { 'complexType': 'SoftLayer_Container_Product_Order_' 'Network_Storage_AsAService', 'packageId': package['id'], 'prices': prices, 'volumeSize': duplicate_size, 'quantity': 1, 'location': location_id, 'duplicateOriginVolumeId': origin_volume['id'], 'useHourlyPricing': hourly_billing_flag } if volume_is_performance: duplicate_order['iops'] = iops return duplicate_order
def prepare_replicant_order_object(manager, snapshot_schedule, location, tier, volume, volume_type): """Prepare the order object which is submitted to the placeOrder() method :param manager: The File or Block manager calling this function :param snapshot_schedule: The primary volume's snapshot schedule to use for replication :param location: The location for the ordered replicant volume :param tier: The tier (IOPS per GB) of the primary volume :param volume: The primary volume as a SoftLayer_Network_Storage object :param volume_type: The type of the primary volume ('file' or 'block') :return: Returns the order object for the Product_Order service's placeOrder() method """ # Ensure the primary volume and snapshot space are not set for cancellation if 'billingItem' not in volume\ or volume['billingItem']['cancellationDate'] != '': raise exceptions.SoftLayerError( 'This volume is set for cancellation; ' 'unable to order replicant volume') for child in volume['billingItem']['activeChildren']: if child['categoryCode'] == 'storage_snapshot_space'\ and child['cancellationDate'] != '': raise exceptions.SoftLayerError( 'The snapshot space for this volume is set for ' 'cancellation; unable to order replicant volume') # Find the ID for the requested location try: location_id = get_location_id(manager, location) except ValueError: raise exceptions.SoftLayerError( "Invalid datacenter name specified. " "Please provide the lower case short name (e.g.: dal09)") # Get sizes and properties needed for the order volume_size = int(volume['capacityGb']) billing_item_category_code = volume['billingItem']['categoryCode'] if billing_item_category_code == 'storage_as_a_service': order_type_is_saas = True elif billing_item_category_code == 'storage_service_enterprise': order_type_is_saas = False else: raise exceptions.SoftLayerError( "A replicant volume cannot be ordered for a primary volume with a " "billing item category code of '%s'" % billing_item_category_code) if 'snapshotCapacityGb' in volume: snapshot_size = int(volume['snapshotCapacityGb']) else: raise exceptions.SoftLayerError( "Snapshot capacity not found for the given primary volume") snapshot_schedule_id = find_snapshot_schedule_id( volume, 'SNAPSHOT_' + snapshot_schedule ) # Use the volume's billing item category code to get the product package package = get_package(manager, billing_item_category_code) # Find prices based on the primary volume's type and billing item category if order_type_is_saas: # 'storage_as_a_service' package complex_type = 'SoftLayer_Container_Product_Order_'\ 'Network_Storage_AsAService' volume_storage_type = volume['storageType']['keyName'] if 'ENDURANCE' in volume_storage_type: volume_is_performance = False if tier is None: tier = find_endurance_tier_iops_per_gb(volume) prices = [ find_price_by_category(package, billing_item_category_code), find_price_by_category(package, 'storage_' + volume_type), find_saas_endurance_space_price(package, volume_size, tier), find_saas_endurance_tier_price(package, tier), find_saas_snapshot_space_price( package, snapshot_size, tier=tier), find_saas_replication_price(package, tier=tier) ] elif 'PERFORMANCE' in volume_storage_type: if not _staas_version_is_v2_or_above(volume): raise exceptions.SoftLayerError( "A replica volume cannot be ordered for this performance " "volume since it does not support Encryption at Rest.") volume_is_performance = True iops = int(volume['provisionedIops']) prices = [ find_price_by_category(package, billing_item_category_code), find_price_by_category(package, 'storage_' + volume_type), find_saas_perform_space_price(package, volume_size), find_saas_perform_iops_price(package, volume_size, iops), find_saas_snapshot_space_price( package, snapshot_size, iops=iops), find_saas_replication_price(package, iops=iops) ] else: raise exceptions.SoftLayerError( "Storage volume does not have a valid storage type " "(with an appropriate keyName to indicate the " "volume is a PERFORMANCE or an ENDURANCE volume)") else: # 'storage_service_enterprise' package complex_type = 'SoftLayer_Container_Product_Order_'\ 'Network_Storage_Enterprise' volume_is_performance = False if tier is None: tier = find_endurance_tier_iops_per_gb(volume) prices = [ find_price_by_category(package, billing_item_category_code), find_price_by_category(package, 'storage_' + volume_type), find_ent_space_price(package, 'endurance', volume_size, tier), find_ent_endurance_tier_price(package, tier), find_ent_space_price(package, 'snapshot', snapshot_size, tier), find_ent_space_price(package, 'replication', volume_size, tier) ] # Determine if hourly billing should be used hourly_billing_flag = utils.lookup(volume, 'billingItem', 'hourlyFlag') if hourly_billing_flag is None: hourly_billing_flag = False # Build and return the order object replicant_order = { 'complexType': complex_type, 'packageId': package['id'], 'prices': prices, 'quantity': 1, 'location': location_id, 'originVolumeId': volume['id'], 'originVolumeScheduleId': snapshot_schedule_id, 'useHourlyPricing': hourly_billing_flag } if order_type_is_saas: replicant_order['volumeSize'] = volume_size if volume_is_performance: replicant_order['iops'] = iops return replicant_order
def prepare_snapshot_order_object(manager, volume, capacity, tier, upgrade): """Prepare the snapshot space order object for the placeOrder() method :param manager: The File or Block manager calling this function :param integer volume: The volume for which snapshot space is ordered :param integer capacity: The snapshot space size to order, in GB :param float tier: The tier level of the volume, in IOPS per GB (optional) :param boolean upgrade: Flag to indicate if this order is an upgrade :return: Returns the order object for the Product_Order service's placeOrder() method """ # Ensure the storage volume has not been cancelled if 'billingItem' not in volume: raise exceptions.SoftLayerError( 'This volume has been cancelled; unable to order snapshot space') # Determine and validate the storage volume's billing item category billing_item_category_code = volume['billingItem']['categoryCode'] if billing_item_category_code == 'storage_as_a_service': order_type_is_saas = True elif billing_item_category_code == 'storage_service_enterprise': order_type_is_saas = False else: raise exceptions.SoftLayerError( "Snapshot space cannot be ordered for a primary volume with a " "billing item category code of '%s'" % billing_item_category_code) # Use the volume's billing item category code to get the product package package = get_package(manager, billing_item_category_code) # Find prices based on the volume's type and billing item category if order_type_is_saas: # 'storage_as_a_service' package volume_storage_type = volume['storageType']['keyName'] if 'ENDURANCE' in volume_storage_type: if tier is None: tier = find_endurance_tier_iops_per_gb(volume) prices = [find_saas_snapshot_space_price( package, capacity, tier=tier)] elif 'PERFORMANCE' in volume_storage_type: if not _staas_version_is_v2_or_above(volume): raise exceptions.SoftLayerError( "Snapshot space cannot be ordered for this performance " "volume since it does not support Encryption at Rest.") iops = int(volume['provisionedIops']) prices = [find_saas_snapshot_space_price( package, capacity, iops=iops)] else: raise exceptions.SoftLayerError( "Storage volume does not have a valid storage type " "(with an appropriate keyName to indicate the " "volume is a PERFORMANCE or an ENDURANCE volume)") else: # 'storage_service_enterprise' package if tier is None: tier = find_endurance_tier_iops_per_gb(volume) prices = [find_ent_space_price(package, 'snapshot', capacity, tier)] # Currently, these types are valid for snapshot space orders, whether # the base volume's order container was Enterprise or AsAService if upgrade: complex_type = 'SoftLayer_Container_Product_Order_'\ 'Network_Storage_Enterprise_SnapshotSpace_Upgrade' else: complex_type = 'SoftLayer_Container_Product_Order_'\ 'Network_Storage_Enterprise_SnapshotSpace' # Determine if hourly billing should be used hourly_billing_flag = utils.lookup(volume, 'billingItem', 'hourlyFlag') if hourly_billing_flag is None: hourly_billing_flag = False # Build and return the order object snapshot_space_order = { 'complexType': complex_type, 'packageId': package['id'], 'prices': prices, 'quantity': 1, 'location': volume['billingItem']['location']['id'], 'volumeId': volume['id'], 'useHourlyPricing': hourly_billing_flag } return snapshot_space_order
def prepare_duplicate_order_object(manager, origin_volume, iops, tier, duplicate_size, duplicate_snapshot_size, volume_type): """Prepare the duplicate order to submit to SoftLayer_Product::placeOrder() :param manager: The File or Block manager calling this function :param origin_volume: The origin volume which is being duplicated :param iops: The IOPS per GB for the duplicant volume (performance) :param tier: The tier level for the duplicant volume (endurance) :param duplicate_size: The requested size for the duplicate volume :param duplicate_snapshot_size: The size for the duplicate snapshot space :param volume_type: The type of the origin volume ('file' or 'block') :return: Returns the order object to be passed to the placeOrder() method of the Product_Order service """ # Verify that the origin volume has not been cancelled if 'billingItem' not in origin_volume: raise exceptions.SoftLayerError( "The origin volume has been cancelled; " "unable to order duplicate volume") # Verify that the origin volume has snapshot space (needed for duplication) if isinstance(utils.lookup(origin_volume, 'snapshotCapacityGb'), str): origin_snapshot_size = int(origin_volume['snapshotCapacityGb']) else: raise exceptions.SoftLayerError( "Snapshot space not found for the origin volume. " "Origin snapshot space is needed for duplication.") # Obtain the datacenter location ID for the duplicate if isinstance(utils.lookup(origin_volume, 'billingItem', 'location', 'id'), int): location_id = origin_volume['billingItem']['location']['id'] else: raise exceptions.SoftLayerError("Cannot find origin volume's location") # If no specific snapshot space was requested for the duplicate, # use the origin snapshot space size if duplicate_snapshot_size is None: duplicate_snapshot_size = origin_snapshot_size # Validate the requested duplicate size, and set the size if none was given duplicate_size = _validate_duplicate_size(origin_volume, duplicate_size, volume_type) # Get the appropriate package for the order # ('storage_as_a_service' is currently used for duplicate volumes) package = get_package(manager, 'storage_as_a_service') # Determine the IOPS or tier level for the duplicate volume, along with # the type and prices for the order origin_storage_type = origin_volume['storageType']['keyName'] if origin_storage_type == 'PERFORMANCE_BLOCK_STORAGE'\ or origin_storage_type == 'PERFORMANCE_BLOCK_STORAGE_REPLICANT'\ or origin_storage_type == 'PERFORMANCE_FILE_STORAGE'\ or origin_storage_type == 'PERFORMANCE_FILE_STORAGE_REPLICANT': volume_is_performance = True iops = _validate_dupl_performance_iops(origin_volume, iops, duplicate_size) # Set up the price array for the order prices = [ find_saas_price_by_category(package, 'storage_as_a_service'), find_saas_price_by_category(package, 'storage_' + volume_type), find_saas_perform_space_price(package, duplicate_size), find_saas_perform_iops_price(package, duplicate_size, iops), ] # Add the price code for snapshot space as well, unless 0 GB was given if duplicate_snapshot_size > 0: prices.append( find_saas_snapshot_space_price(package, duplicate_snapshot_size, iops=iops)) elif origin_storage_type == 'ENDURANCE_BLOCK_STORAGE'\ or origin_storage_type == 'ENDURANCE_BLOCK_STORAGE_REPLICANT'\ or origin_storage_type == 'ENDURANCE_FILE_STORAGE'\ or origin_storage_type == 'ENDURANCE_FILE_STORAGE_REPLICANT': volume_is_performance = False tier = _validate_dupl_endurance_tier(origin_volume, tier) # Set up the price array for the order prices = [ find_saas_price_by_category(package, 'storage_as_a_service'), find_saas_price_by_category(package, 'storage_' + volume_type), find_saas_endurance_space_price(package, duplicate_size, tier), find_saas_endurance_tier_price(package, tier), ] # Add the price code for snapshot space as well, unless 0 GB was given if duplicate_snapshot_size > 0: prices.append( find_saas_snapshot_space_price(package, duplicate_snapshot_size, tier_level=tier)) else: raise exceptions.SoftLayerError( "Origin volume does not have a valid storage type " "(with an appropriate keyName to indicate the " "volume is a PERFORMANCE or ENDURANCE volume)") duplicate_order = { 'complexType': 'SoftLayer_Container_Product_Order_' 'Network_Storage_AsAService', 'packageId': package['id'], 'prices': prices, 'volumeSize': duplicate_size, 'quantity': 1, 'location': location_id, 'duplicateOriginVolumeId': origin_volume['id'], } if volume_is_performance: duplicate_order['iops'] = iops return duplicate_order
def cli(env, identifier, no_vs, no_hardware): """Get subnet details.""" mgr = SoftLayer.NetworkManager(env.client) subnet_id = helpers.resolve_id(mgr.resolve_subnet_ids, identifier, name='subnet') mask = 'mask[ipAddresses[id, ipAddress,note], datacenter, virtualGuests, hardware]' subnet = mgr.get_subnet(subnet_id, mask=mask) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' table.add_row(['id', subnet['id']]) table.add_row([ 'identifier', '%s/%s' % (subnet['networkIdentifier'], str(subnet['cidr'])) ]) table.add_row(['subnet type', subnet['subnetType']]) table.add_row( ['network space', utils.lookup(subnet, 'networkVlan', 'networkSpace')]) table.add_row(['gateway', subnet.get('gateway', formatting.blank())]) table.add_row( ['broadcast', subnet.get('broadcastAddress', formatting.blank())]) table.add_row(['datacenter', subnet['datacenter']['name']]) table.add_row( ['usable ips', subnet.get('usableIpAddressCount', formatting.blank())]) table.add_row(['note', subnet.get('note', formatting.blank())]) table.add_row(['tags', formatting.tags(subnet.get('tagReferences'))]) ip_address = subnet.get('ipAddresses') ip_table = formatting.KeyValueTable(['id', 'ip', 'note']) for address in ip_address: ip_table.add_row( [address.get('id'), address.get('ipAddress'), address.get('note')]) table.add_row(['ipAddresses', ip_table]) if not no_vs: if subnet['virtualGuests']: vs_table = formatting.Table( ['hostname', 'domain', 'public_ip', 'private_ip']) for vsi in subnet['virtualGuests']: vs_table.add_row([ vsi['hostname'], vsi['domain'], vsi.get('primaryIpAddress'), vsi.get('primaryBackendIpAddress') ]) table.add_row(['vs', vs_table]) else: table.add_row(['vs', formatting.blank()]) if not no_hardware: if subnet['hardware']: hw_table = formatting.Table( ['hostname', 'domain', 'public_ip', 'private_ip']) for hardware in subnet['hardware']: hw_table.add_row([ hardware['hostname'], hardware['domain'], hardware.get('primaryIpAddress'), hardware.get('primaryBackendIpAddress') ]) table.add_row(['hardware', hw_table]) else: table.add_row(['hardware', formatting.blank()]) env.fout(table)
def _get_hardware_bandwidth(env, start, end): hw_call = env.client.call('Account', 'getHardware', iter=True, mask='id,hostname,metricTrackingObject.id,' 'virtualRack[id,bandwidthAllotmentTypeId]') types = [ { 'keyName': 'PUBLICIN', 'name': 'publicIn', 'summaryType': 'counter' }, { 'keyName': 'PUBLICOUT', 'name': 'publicOut', 'summaryType': 'counter' }, { 'keyName': 'PRIVATEIN', 'name': 'privateIn', 'summaryType': 'counter' }, { 'keyName': 'PRIVATEOUT', 'name': 'privateOut', 'summaryType': 'counter' }, ] with click.progressbar(list(hw_call), label='Calculating for hardware', file=sys.stderr) as hws: for instance in hws: if not utils.lookup(instance, 'metricTrackingObject', 'id'): continue pool_name = None if utils.lookup(instance, 'virtualRack', 'bandwidthAllotmentTypeId') == 2: pool_name = utils.lookup(instance, 'virtualRack', 'name') yield { 'id': instance['id'], 'type': 'hardware', 'name': instance['hostname'], 'pool': pool_name, 'data': env.client.call( 'Metric_Tracking_Object', 'getSummaryData', start.strftime('%Y-%m-%d %H:%M:%S %Z'), end.strftime('%Y-%m-%d %H:%M:%S %Z'), types, 3600, id=instance['metricTrackingObject']['id'], ), }
def cli(env, identifier, passwords=False, price=False): """Get details for a virtual server.""" vsi = SoftLayer.VSManager(env.client) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS') result = vsi.get_instance(vs_id) result = utils.NestedDict(result) table.add_row(['id', result['id']]) table.add_row(['guid', result['globalIdentifier']]) table.add_row(['hostname', result['hostname']]) table.add_row(['domain', result['domain']]) table.add_row(['fqdn', result['fullyQualifiedDomainName']]) table.add_row([ 'status', formatting.FormattedItem( result['status']['keyName'] or formatting.blank(), result['status']['name'] or formatting.blank()) ]) table.add_row([ 'state', formatting.FormattedItem( utils.lookup(result, 'powerState', 'keyName'), utils.lookup(result, 'powerState', 'name'), ) ]) table.add_row(['active_transaction', formatting.active_txn(result)]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) _cli_helper_dedicated_host(env, result, table) operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {} table.add_row(['os', operating_system.get('name') or formatting.blank()]) table.add_row( ['os_version', operating_system.get('version') or formatting.blank()]) table.add_row(['cores', result['maxCpu']]) table.add_row(['memory', formatting.mb_to_gb(result['maxMemory'])]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row(['private_only', result['privateNetworkOnlyFlag']]) table.add_row(['private_cpu', result['dedicatedAccountHostOnlyFlag']]) table.add_row(['created', result['createDate']]) table.add_row(['modified', result['modifyDate']]) if utils.lookup(result, 'billingItem') != []: table.add_row([ 'owner', formatting.FormattedItem( utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') or formatting.blank(), ) ]) else: table.add_row(['owner', formatting.blank()]) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) if result.get('networkComponents'): secgroup_table = formatting.Table(['interface', 'id', 'name']) has_secgroups = False for comp in result.get('networkComponents'): interface = 'PRIVATE' if comp['port'] == 0 else 'PUBLIC' for binding in comp['securityGroupBindings']: has_secgroups = True secgroup = binding['securityGroup'] secgroup_table.add_row([ interface, secgroup['id'], secgroup.get('name') or formatting.blank() ]) if has_secgroups: table.add_row(['security_groups', secgroup_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if price: total_price = utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount') or 0 total_price += sum( p['nextInvoiceTotalRecurringAmount'] for p in utils.lookup(result, 'billingItem', 'children') or []) table.add_row(['price_rate', total_price]) if passwords: pass_table = formatting.Table(['software', 'username', 'password']) for component in result['softwareComponents']: for item in component['passwords']: pass_table.add_row([ utils.lookup(component, 'softwareLicense', 'softwareDescription', 'name'), item['username'], item['password'], ]) table.add_row(['users', pass_table]) table.add_row(['tags', formatting.tags(result['tagReferences'])]) # Test to see if this actually has a primary (public) ip address try: if not result['privateNetworkOnlyFlag']: ptr_domains = env.client.call( 'Virtual_Guest', 'getReverseDomainRecords', id=vs_id, ) for ptr_domain in ptr_domains: for ptr in ptr_domain['resourceRecords']: table.add_row(['ptr', ptr['data']]) except SoftLayer.SoftLayerAPIError: pass env.fout(table)
def order_options(env, datacenter): """Prints options for order a LBaaS""" print("Prints options for ordering") mgr = SoftLayer.LoadBalancerManager(env.client) net_mgr = SoftLayer.NetworkManager(env.client) package = mgr.lbaas_order_options() for region in package['regions']: dc_name = utils.lookup(region, 'location', 'location', 'name') # Skip locations if they are not the one requested. if datacenter and dc_name != datacenter: continue this_table = formatting.Table(['Prices', 'Private Subnets'], title="{}: {}".format( region['keyname'], region['description'])) l_groups = [] for group in region['location']['location']['groups']: l_groups.append(group.get('id')) # Price lookups prices = [] price_table = formatting.KeyValueTable(['KeyName', 'Cost']) for item in package['items']: i_price = {'keyName': item['keyName']} for price in item.get('prices', []): if not price.get('locationGroupId'): i_price['default_price'] = price.get('hourlyRecurringFee') elif price.get('locationGroupId') in l_groups: i_price['region_price'] = price.get('hourlyRecurringFee') prices.append(i_price) for price in prices: if price.get('region_price'): price_table.add_row( [price.get('keyName'), price.get('region_price')]) else: price_table.add_row( [price.get('keyName'), price.get('default_price')]) # Vlan/Subnet Lookups mask = "mask[networkVlan,podName,addressSpace]" subnets = net_mgr.list_subnets(datacenter=dc_name, network_space='PRIVATE', mask=mask) subnet_table = formatting.Table(['Id', 'Subnet', 'Vlan']) for subnet in subnets: # Only show these types, easier to filter here than in an API call. if subnet.get('subnetType') != 'PRIMARY' and subnet.get( 'subnetType') != 'ADDITIONAL_PRIMARY': continue space = "{}/{}".format(subnet.get('networkIdentifier'), subnet.get('cidr')) vlan = "{}.{}".format(subnet['podName'], subnet['networkVlan']['vlanNumber']) subnet_table.add_row([subnet.get('id'), space, vlan]) this_table.add_row([price_table, subnet_table]) env.fout(this_table)
def cli(env, identifier, credentials): """Detail firewall. EXAMPLES: slcli firewall detail vs:12345 slcli firewall detail --credentials true multiVlan:456789 """ mgr = SoftLayer.FirewallManager(env.client) firewall_type, firewall_id = firewall.parse_id(identifier) if firewall_type in ('vs', 'server', 'vlan', 'multiVlan'): if firewall_type == 'vlan': _firewall = mgr.get_instance(firewall_id) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' table.add_row(['id', _firewall.get('id')]) table.add_row( ['primaryIpAddress', _firewall.get('primaryIpAddress')]) table.add_row([ 'datacenter', utils.lookup(_firewall, 'datacenter', 'longName') ]) table.add_row([ 'networkVlan', utils.lookup(_firewall, 'networkVlan', 'name') ]) table.add_row([ 'networkVlaniD', utils.lookup(_firewall, 'networkVlan', 'id') ]) rules = mgr.get_dedicated_fwl_rules(firewall_id) table.add_row(['rules', get_rules_table(rules)]) if firewall_type == 'multiVlan': _firewall = mgr.get_instance(firewall_id) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' table.add_row( ['name', utils.lookup(_firewall, 'networkGateway', 'name')]) table.add_row([ 'datacenter', utils.lookup(_firewall, 'datacenter', 'longName') ]) table.add_row([ 'public ip', utils.lookup(_firewall, 'networkGateway', 'publicIpAddress', 'ipAddress') ]) table.add_row([ 'private ip', utils.lookup(_firewall, 'networkGateway', 'privateIpAddress', 'ipAddress') ]) table.add_row([ 'public ipv6', utils.lookup(_firewall, 'networkGateway', 'publicIpv6Address', 'ipAddress') ]) table.add_row([ 'public vlan', utils.lookup(_firewall, 'networkGateway', 'publicVlan', 'vlanNumber') ]) table.add_row([ 'private vlan', utils.lookup(_firewall, 'networkGateway', 'privateVlan', 'vlanNumber') ]) table.add_row(['type', _firewall.get('firewallType')]) if credentials: table.add_row([ 'fortiGate username', utils.lookup(_firewall, 'managementCredentials', 'username') ]) table.add_row([ 'fortiGate password', utils.lookup(_firewall, 'managementCredentials', 'password') ]) rules = mgr.get_dedicated_fwl_rules(firewall_id) if len(rules) != 0: table.add_row(['rules', get_rules_table(rules)]) else: table.add_row(['rules', '-']) if firewall_type == 'vs' or firewall_type == 'server': rules = mgr.get_standard_fwl_rules(firewall_id) table = get_rules_table(rules) env.fout(table) else: click.secho( 'Invalid firewall type %s: firewall type should be either vlan, multiVlan, vs or server.' % firewall_type, fg='red') return
def cli(env, identifier, passwords=False, price=False): """Get details for a virtual server.""" vsi = SoftLayer.VSManager(env.client) table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' table.align['Value'] = 'l' vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS') result = vsi.get_instance(vs_id) result = utils.NestedDict(result) table.add_row(['id', result['id']]) table.add_row(['guid', result['globalIdentifier']]) table.add_row(['hostname', result['hostname']]) table.add_row(['domain', result['domain']]) table.add_row(['fqdn', result['fullyQualifiedDomainName']]) table.add_row([ 'status', formatting.FormattedItem( result['status']['keyName'] or formatting.blank(), result['status']['name'] or formatting.blank()) ]) table.add_row([ 'state', formatting.FormattedItem( utils.lookup(result, 'powerState', 'keyName'), utils.lookup(result, 'powerState', 'name'), ) ]) table.add_row(['active_transaction', formatting.active_txn(result)]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {} table.add_row([ 'os', formatting.FormattedItem( operating_system.get('version') or formatting.blank(), operating_system.get('name') or formatting.blank()) ]) table.add_row( ['os_version', operating_system.get('version') or formatting.blank()]) table.add_row(['cores', result['maxCpu']]) table.add_row(['memory', formatting.mb_to_gb(result['maxMemory'])]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row(['private_only', result['privateNetworkOnlyFlag']]) table.add_row(['private_cpu', result['dedicatedAccountHostOnlyFlag']]) table.add_row(['created', result['createDate']]) table.add_row(['modified', result['modifyDate']]) if utils.lookup(result, 'billingItem') != []: table.add_row([ 'owner', formatting.FormattedItem( utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') or formatting.blank(), ) ]) else: table.add_row(['owner', formatting.blank()]) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if price: table.add_row(['price rate', result['billingItem']['recurringFee']]) if passwords: pass_table = formatting.Table(['username', 'password']) for item in result['operatingSystem']['passwords']: pass_table.add_row([item['username'], item['password']]) table.add_row(['users', pass_table]) tag_row = [] for tag_detail in result['tagReferences']: tag = utils.lookup(tag_detail, 'tag', 'name') if tag is not None: tag_row.append(tag) if tag_row: table.add_row(['tags', formatting.listing(tag_row, separator=', ')]) # Test to see if this actually has a primary (public) ip address try: if not result['privateNetworkOnlyFlag']: ptr_domains = env.client.call( 'Virtual_Guest', 'getReverseDomainRecords', id=vs_id, ) for ptr_domain in ptr_domains: for ptr in ptr_domain['resourceRecords']: table.add_row(['ptr', ptr['data']]) except SoftLayer.SoftLayerAPIError: pass env.fout(table)
def cli(env, identifier): """Get details of an Autoscale groups.""" autoscale = AutoScaleManager(env.client) group = autoscale.details(identifier) # Group Config Table table = formatting.KeyValueTable(["Group", "Value"]) table.align['Group'] = 'l' table.align['Value'] = 'l' table.add_row(['Id', group.get('id')]) # Ideally we would use regionalGroup->preferredDatacenter, but that generates an error. table.add_row(['Datacenter', group['regionalGroup']['locations'][0]['longName']]) table.add_row(['Termination', utils.lookup(group, 'terminationPolicy', 'name')]) table.add_row(['Minimum Members', group.get('minimumMemberCount')]) table.add_row(['Maximum Members', group.get('maximumMemberCount')]) table.add_row(['Current Members', group.get('virtualGuestMemberCount')]) table.add_row(['Cooldown', "{} seconds".format(group.get('cooldown'))]) table.add_row(['Last Action', utils.clean_time(group.get('lastActionDate'))]) for network in group.get('networkVlans', []): network_type = utils.lookup(network, 'networkVlan', 'networkSpace') router = utils.lookup(network, 'networkVlan', 'primaryRouter', 'hostname') vlan_number = utils.lookup(network, 'networkVlan', 'vlanNumber') vlan_name = "{}.{}".format(router, vlan_number) table.add_row([network_type, vlan_name]) env.fout(table) # Template Config Table config_table = formatting.KeyValueTable(["Template", "Value"]) config_table.align['Template'] = 'l' config_table.align['Value'] = 'l' template = group.get('virtualGuestMemberTemplate') config_table.add_row(['Hostname', template.get('hostname')]) config_table.add_row(['Domain', template.get('domain')]) config_table.add_row(['Core', template.get('startCpus')]) config_table.add_row(['Ram', template.get('maxMemory')]) network = template.get('networkComponents') config_table.add_row(['Network', network[0]['maxSpeed'] if network else 'Default']) ssh_keys = template.get('sshKeys', []) ssh_manager = SoftLayer.SshKeyManager(env.client) for key in ssh_keys: # Label isn't included when retrieved from the AutoScale group... ssh_key = ssh_manager.get_key(key.get('id')) config_table.add_row(['SSH Key {}'.format(ssh_key.get('id')), ssh_key.get('label')]) disks = template.get('blockDevices', []) disk_type = "Local" if template.get('localDiskFlag') else "SAN" for disk in disks: disk_image = disk.get('diskImage') config_table.add_row(['{} Disk {}'.format(disk_type, disk.get('device')), disk_image.get('capacity')]) config_table.add_row(['OS', template.get('operatingSystemReferenceCode')]) config_table.add_row(['Post Install', template.get('postInstallScriptUri') or 'None']) env.fout(config_table) # Policy Config Table policy_table = formatting.KeyValueTable(["Policy", "Cooldown"]) policies = group.get('policies', []) for policy in policies: policy_table.add_row([policy.get('name'), policy.get('cooldown') or group.get('cooldown')]) env.fout(policy_table) # Active Guests member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Active Guests") guests = group.get('virtualGuestMembers', []) for guest in guests: real_guest = guest.get('virtualGuest') member_table.add_row([ real_guest.get('id'), real_guest.get('hostname'), utils.clean_time(real_guest.get('provisionDate')) ]) env.fout(member_table)
def cli(env, identifier, passwords, price): """Get details for a hardware device.""" hardware = SoftLayer.HardwareManager(env.client) table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' table.align['Value'] = 'l' hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware') result = hardware.get_hardware(hardware_id) result = utils.NestedDict(result) table.add_row(['id', result['id']]) table.add_row(['guid', result['globalIdentifier'] or formatting.blank()]) table.add_row(['hostname', result['hostname']]) table.add_row(['domain', result['domain']]) table.add_row(['fqdn', result['fullyQualifiedDomainName']]) table.add_row(['status', result['hardwareStatus']['status']]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) table.add_row(['cores', result['processorPhysicalCoreAmount']]) table.add_row(['memory', formatting.gb(result['memoryCapacity'])]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row([ 'ipmi_ip', result['networkManagementIpAddress'] or formatting.blank() ]) table.add_row([ 'os', formatting.FormattedItem( result['operatingSystem']['softwareLicense']['softwareDescription'] ['referenceCode'] or formatting.blank(), result['operatingSystem'] ['softwareLicense']['softwareDescription']['name'] or formatting.blank()) ]) table.add_row(['created', result['provisionDate'] or formatting.blank()]) if utils.lookup(result, 'billingItem') != []: table.add_row([ 'owner', formatting.FormattedItem( utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') or formatting.blank(), ) ]) else: table.add_row(['owner', formatting.blank()]) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if price: table.add_row([ 'price rate', utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount') ]) if passwords: pass_table = formatting.Table(['username', 'password']) for item in result['operatingSystem']['passwords']: pass_table.add_row([item['username'], item['password']]) table.add_row(['users', pass_table]) pass_table = formatting.Table(['ipmi_username', 'password']) for item in result['remoteManagementAccounts']: pass_table.add_row([item['username'], item['password']]) table.add_row(['remote users', pass_table]) tag_row = [] for tag_detail in result['tagReferences']: tag = utils.lookup(tag_detail, 'tag', 'name') if tag is not None: tag_row.append(tag) if tag_row: table.add_row(['tags', formatting.listing(tag_row, separator=',')]) # Test to see if this actually has a primary (public) ip address try: if not result['privateNetworkOnlyFlag']: ptr_domains = ( env.client['Hardware_Server'].getReverseDomainRecords( id=hardware_id)) for ptr_domain in ptr_domains: for ptr in ptr_domain['resourceRecords']: table.add_row(['ptr', ptr['data']]) except SoftLayer.SoftLayerAPIError: pass env.fout(table)
def order_guest(self, guest_object, test=False): """Uses Product_Order::placeOrder to create a virtual guest. Useful when creating a virtual guest with options not supported by Virtual_Guest::createObject specifically ipv6 support. :param dictionary guest_object: See SoftLayer.CLI.virt.create._parse_create_args Example:: new_vsi = { 'domain': u'test01.labs.sftlyr.ws', 'hostname': u'minion05', 'datacenter': u'hkg02', 'flavor': 'BL1_1X2X100' 'dedicated': False, 'private': False, 'os_code' : u'UBUNTU_LATEST', 'hourly': True, 'ssh_keys': [1234], 'disks': ('100','25'), 'local_disk': True, 'tags': 'test, pleaseCancel', 'public_security_groups': [12, 15], 'ipv6': True } vsi = mgr.order_guest(new_vsi) # vsi will have the newly created vsi receipt. # vsi['orderDetails']['virtualGuests'] will be an array of created Guests print vsi """ tags = guest_object.pop('tags', None) template = self.verify_create_instance(**guest_object) if guest_object.get('ipv6'): ipv6_price = self.ordering_manager.get_price_id_list( 'PUBLIC_CLOUD_SERVER', ['1_IPV6_ADDRESS']) template['prices'].append({'id': ipv6_price[0]}) # Notice this is `userdata` from the cli, but we send it in as `userData` if guest_object.get('userdata'): # SL_Virtual_Guest::generateOrderTemplate() doesn't respect userData, so we need to add it ourself template['virtualGuests'][0]['userData'] = [{ "value": guest_object.get('userdata') }] if guest_object.get('host_id'): template['hostId'] = guest_object.get('host_id') if guest_object.get('placement_id'): template['virtualGuests'][0][ 'placementGroupId'] = guest_object.get('placement_id') if test: result = self.client.call('Product_Order', 'verifyOrder', template) else: result = self.client.call('Product_Order', 'placeOrder', template) if tags is not None: virtual_guests = utils.lookup(result, 'orderDetails', 'virtualGuests') for guest in virtual_guests: self.set_tags(tags, guest_id=guest['id']) return result
def cli(env, identifier, passwords, price, components): """Get details for a hardware device.""" hardware = SoftLayer.HardwareManager(env.client) table = formatting.KeyValueTable(['name', 'value']) table.align['name'] = 'r' table.align['value'] = 'l' hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware') result = hardware.get_hardware(hardware_id) result = utils.NestedDict(result) hard_drives = hardware.get_hard_drives(hardware_id) operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {} memory = formatting.gb(result.get('memoryCapacity', 0)) owner = None if utils.lookup(result, 'billingItem') != []: owner = utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username') table_hard_drives = formatting.Table(['Name', 'Capacity', 'Serial #']) for drives in hard_drives: name = drives['hardwareComponentModel']['manufacturer'] + " " + drives[ 'hardwareComponentModel']['name'] capacity = str( drives['hardwareComponentModel']['hardwareGenericComponentModel'] ['capacity']) + " " + str( drives['hardwareComponentModel'] ['hardwareGenericComponentModel']['units']) serial = drives['serialNumber'] table_hard_drives.add_row([name, capacity, serial]) table.add_row(['id', result['id']]) table.add_row(['guid', result['globalIdentifier'] or formatting.blank()]) table.add_row(['hostname', result['hostname']]) table.add_row(['domain', result['domain']]) table.add_row(['fqdn', result['fullyQualifiedDomainName']]) table.add_row(['status', result['hardwareStatus']['status']]) table.add_row( ['datacenter', result['datacenter']['name'] or formatting.blank()]) table.add_row(['cores', result['processorPhysicalCoreAmount']]) table.add_row(['memory', memory]) table.add_row(['drives', table_hard_drives]) table.add_row( ['public_ip', result['primaryIpAddress'] or formatting.blank()]) table.add_row([ 'private_ip', result['primaryBackendIpAddress'] or formatting.blank() ]) table.add_row([ 'ipmi_ip', result['networkManagementIpAddress'] or formatting.blank() ]) table.add_row(['os', operating_system.get('name') or formatting.blank()]) table.add_row( ['os_version', operating_system.get('version') or formatting.blank()]) table.add_row(['created', result['provisionDate'] or formatting.blank()]) table.add_row(['owner', owner or formatting.blank()]) last_transaction = "{} ({})".format( utils.lookup(result, 'lastTransaction', 'transactionGroup', 'name'), utils.clean_time(utils.lookup(result, 'lastTransaction', 'modifyDate'))) table.add_row(['last_transaction', last_transaction]) table.add_row( ['billing', 'Hourly' if result['hourlyBillingFlag'] else 'Monthly']) vlan_table = formatting.Table(['type', 'number', 'id']) for vlan in result['networkVlans']: vlan_table.add_row( [vlan['networkSpace'], vlan['vlanNumber'], vlan['id']]) table.add_row(['vlans', vlan_table]) bandwidth = hardware.get_bandwidth_allocation(hardware_id) bw_table = _bw_table(bandwidth) table.add_row(['Bandwidth', bw_table]) system_table = _system_table(result['activeComponents']) table.add_row(['System_data', system_table]) if result.get('notes'): table.add_row(['notes', result['notes']]) if price: total_price = utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount') or 0 price_table = formatting.Table( ['Item', 'CategoryCode', 'Recurring Price']) price_table.align['Item'] = 'l' price_table.add_row(['Total', '-', total_price]) for item in utils.lookup(result, 'billingItem', 'nextInvoiceChildren') or []: price_table.add_row([ item['description'], item['categoryCode'], item['nextInvoiceTotalRecurringAmount'] ]) table.add_row(['prices', price_table]) if passwords: pass_table = formatting.Table(['username', 'password']) for item in result['operatingSystem']['passwords']: pass_table.add_row([item['username'], item['password']]) table.add_row(['users', pass_table]) pass_table = formatting.Table(['ipmi_username', 'password']) for item in result['remoteManagementAccounts']: pass_table.add_row([item['username'], item['password']]) table.add_row(['remote users', pass_table]) if components: components = hardware.get_components(identifier) components_table = formatting.Table( ['name', 'Firmware version', 'Firmware build date', 'Type']) components_table.align['date'] = 'l' component_ids = [] for hw_component in components: if hw_component['id'] not in component_ids: firmware = hw_component['hardwareComponentModel']['firmwares'][ 0] components_table.add_row([ utils.lookup(hw_component, 'hardwareComponentModel', 'longDescription'), utils.lookup(firmware, 'version'), utils.clean_time(utils.lookup(firmware, 'createDate')), utils.lookup(hw_component, 'hardwareComponentModel', 'hardwareGenericComponentModel', 'hardwareComponentType', 'keyName') ]) component_ids.append(hw_component['id']) table.add_row(['components', components_table]) table.add_row(['tags', formatting.tags(result['tagReferences'])]) env.fout(table)
def add_subnet(self, subnet_type, quantity=None, vlan_id=None, version=4, test_order=False): """Orders a new subnet :param str subnet_type: Type of subnet to add: private, public, global :param int quantity: Number of IPs in the subnet :param int vlan_id: VLAN id for the subnet to be placed into :param int version: 4 for IPv4, 6 for IPv6 :param bool test_order: If true, this will only verify the order. """ package = self.client['Product_Package'] category = 'sov_sec_ip_addresses_priv' desc = '' if version == 4: if subnet_type == 'global': quantity = 0 category = 'global_ipv4' elif subnet_type == 'public': category = 'sov_sec_ip_addresses_pub' else: category = 'static_ipv6_addresses' if subnet_type == 'global': quantity = 0 category = 'global_ipv6' desc = 'Global' elif subnet_type == 'public': desc = 'Portable' # In the API, every non-server item is contained within package ID 0. # This means that we need to get all of the items and loop through them # looking for the items we need based upon the category, quantity, and # item description. price_id = None quantity_str = str(quantity) for item in package.getItems(id=0, mask='itemCategory'): category_code = utils.lookup(item, 'itemCategory', 'categoryCode') if all([category_code == category, item.get('capacity') == quantity_str, version == 4 or (version == 6 and desc in item['description'])]): price_id = item['prices'][0]['id'] break if not price_id: raise TypeError('Invalid combination specified for ordering a' ' subnet.') order = { 'packageId': 0, 'prices': [{'id': price_id}], 'quantity': 1, # This is necessary in order for the XML-RPC endpoint to select the # correct order container 'complexType': 'SoftLayer_Container_Product_Order_Network_Subnet', } if subnet_type != 'global': order['endPointVlanId'] = vlan_id if test_order: return self.client['Product_Order'].verifyOrder(order) else: return self.client['Product_Order'].placeOrder(order)
def cli(env, volume_id): """Display details for a specified volume.""" block_manager = SoftLayer.BlockStorageManager(env.client) block_volume = block_manager.get_block_volume_details(volume_id) block_volume = utils.NestedDict(block_volume) table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' table.align['Value'] = 'l' storage_type = block_volume['storageType']['keyName'].split('_').pop(0) table.add_row(['ID', block_volume['id']]) table.add_row(['Username', block_volume['username']]) table.add_row(['Type', storage_type]) table.add_row(['Capacity (GB)', "%iGB" % block_volume['capacityGb']]) table.add_row(['LUN Id', "%s" % block_volume['lunId']]) if block_volume.get('provisionedIops'): table.add_row(['IOPs', int(block_volume['provisionedIops'])]) if block_volume.get('storageTierLevel'): table.add_row([ 'Endurance Tier', block_volume['storageTierLevel'], ]) table.add_row([ 'Data Center', block_volume['serviceResource']['datacenter']['name'], ]) table.add_row([ 'Target IP', block_volume['serviceResourceBackendIpAddress'], ]) if block_volume['snapshotCapacityGb']: table.add_row([ 'Snapshot Capacity (GB)', block_volume['snapshotCapacityGb'], ]) if 'snapshotSizeBytes' in block_volume['parentVolume']: table.add_row([ 'Snapshot Used (Bytes)', block_volume['parentVolume']['snapshotSizeBytes'], ]) table.add_row([ '# of Active Transactions', "%i" % block_volume['activeTransactionCount'] ]) if block_volume['activeTransactions']: for trans in block_volume['activeTransactions']: if 'transactionStatus' in trans and 'friendlyName' in trans[ 'transactionStatus']: table.add_row([ 'Ongoing Transaction', trans['transactionStatus']['friendlyName'] ]) table.add_row([ 'Replicant Count', "%u" % block_volume.get('replicationPartnerCount', 0) ]) if block_volume['replicationPartnerCount'] > 0: # This if/else temporarily handles a bug in which the SL API # returns a string or object for 'replicationStatus'; it seems that # the type is string for File volumes and object for Block volumes if 'message' in block_volume['replicationStatus']: table.add_row([ 'Replication Status', "%s" % block_volume['replicationStatus']['message'] ]) else: table.add_row([ 'Replication Status', "%s" % block_volume['replicationStatus'] ]) replicant_list = [] for replicant in block_volume['replicationPartners']: replicant_table = formatting.Table( ['Replicant ID', replicant['id']]) replicant_table.add_row( ['Volume Name', utils.lookup(replicant, 'username')]) replicant_table.add_row([ 'Target IP', utils.lookup(replicant, 'serviceResourceBackendIpAddress') ]) replicant_table.add_row([ 'Data Center', utils.lookup(replicant, 'serviceResource', 'datacenter', 'name') ]) replicant_table.add_row([ 'Schedule', utils.lookup(replicant, 'replicationSchedule', 'type', 'keyname') ]) replicant_list.append(replicant_table) table.add_row(['Replicant Volumes', replicant_list]) if block_volume.get('originalVolumeSize'): original_volume_info = formatting.Table(['Property', 'Value']) original_volume_info.add_row( ['Original Volume Size', block_volume['originalVolumeSize']]) if block_volume.get('originalVolumeName'): original_volume_info.add_row( ['Original Volume Name', block_volume['originalVolumeName']]) if block_volume.get('originalSnapshotName'): original_volume_info.add_row([ 'Original Snapshot Name', block_volume['originalSnapshotName'] ]) table.add_row(['Original Volume Properties', original_volume_info]) env.fout(table)