def everything(ctx): """Destroy everything you own.""" click.confirm(" Are you sure you want to destroy your entire lab?", abort=True) click.confirm( " Really sure? You cannot undo this, just like you cannot un-bake a cake.", abort=True) consume_task(ctx.obj.vlab_api, endpoint='/api/1/inf/power', body={ 'machine': 'all', 'power': 'off' }, message='Powering down your lab', timeout=300, pause=5) consume_task(ctx.obj.vlab_api, endpoint='/api/1/inf/inventory', message='Destroying inventory', method='DELETE') resp = consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/vlan', message='Determining what networks you own', method='GET') vlans = resp.json()['content'] tasks = {} with Spinner('Deleting networks'): for vlan in vlans.keys(): resp = ctx.obj.vlab_api.delete('/api/2/inf/vlan', json={'vlan-name': vlan}) tasks[vlan] = resp.links['status']['url'] block_on_tasks(ctx.obj.vlab_api, tasks, pause=1)
def router(ctx, images): """Display information about network routers in your lab""" if images: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/router/image', base_endpoint=False, message= 'Collecting available versions of network routers for deployment', method='GET').json()['content'] rows = [] for img in info['image']: rows.append(Version(img, name='Router')) table = get_formatted_table(sorted(rows)) click.echo('\n{}\n'.format(table)) else: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/router', message= 'Collecting information about the network routers in your lab', method='GET').json()['content'] output = vm_table_view(ctx.obj.vlab_api, info) if not output: output = 'You do not own any network Routers' click.echo(output)
def ana(ctx, images): """Display information about Avamar NDMP Accelerators in your lab""" if images: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/avamar/ndmp-accelerator/image', base_endpoint=False, message= 'Collecting available versions of Avamar NDMP Accelerators for deployment', method='GET').json()['content'] rows = [] for img in info['image']: rows.append(img) output = get_formatted_table(sorted(rows)) click.echo('\n{}\n'.format(output)) else: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/avamar/ndmp-accelerator', message= 'Collecting information about your Avamar NDMP Accelerators', method='GET').json() output = vm_table_view(ctx.obj.vlab_api, info['content']) if not output: output = 'You do not own any Avamar NDMP Accelerators instances' click.echo(output)
def claritynow(ctx, images): """Display information about ClarityNow instances in your lab""" if images: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/claritynow/image', base_endpoint=False, message= 'Collecting available versions of ClarityNow for deployment', method='GET').json()['content'] rows = [] for img in info['image']: rows.append(img) table = get_formatted_table(sorted(rows)) click.echo('\n{}\n'.format(table)) else: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/claritynow', message='Collecting information about your ClarityNow instances', method='GET').json() output = vm_table_view(ctx.obj.vlab_api, info['content']) if not output: output = 'You do not own any ClarityNow instances' click.echo(output)
def onefs(ctx, images): """Display information about vOneFS nodes in your lab""" if images: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/onefs/image', base_endpoint=False, message='Collecting available versions of OneFS for deployment', method='GET').json()['content'] rows = [] for img in info['image']: rows.append(img) table = get_formatted_table(sorted(rows)) click.echo('\n{}\n'.format(table)) else: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/onefs', message='Collecting information about your OneFS nodes', method='GET').json() ordered_nodes = sort_node_list(info['content']) output = vm_table_view(ctx.obj.vlab_api, ordered_nodes) if not output: output = 'You do not own any OneFS nodes' click.echo(output)
def _change_power_state(api, power_state, machine_name): """The API for powering on/off/restarting is identical, so why duplicate code? :Returns: None :param api: A valid API connection to vLab :type vlab_api: vLabApi :param power_state: What to do, like power on/off/restart a VM :type power_state: String :param machine_name: The name of the VM to change the power state of :type machine_name: String """ if power_state == 'restart': msg = 'Power cycling {}'.format(machine_name) else: msg = 'Powering {} {}'.format(power_state, machine_name) body = {'machine': machine_name, 'power': power_state} consume_task(api, endpoint='/api/1/inf/power', message=msg, body=body, timeout=600, pause=5) click.echo('OK!')
def gateway(ctx): """Delete your network gateway""" consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/gateway', message='Deleting your gateway', method='DELETE') click.echo('OK!')
def superna(ctx, images): """Display information about Superna Eyeglass servers in your lab""" if images: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/superna/image', base_endpoint=False, message= 'Collecting available versions of Superna Eyeglass servers for deployment', method='GET').json()['content'] rows = [] for img in info['image']: rows.append(img) output = get_formatted_table(sorted(rows)) click.echo('\n{}\n'.format(output)) else: info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/superna', message= 'Collecting information about your Superna Eyeglass servers', method='GET').json() output = vm_table_view(ctx.obj.vlab_api, info['content']) if not output: output = 'You do not own any Superna Eyeglass servers' click.echo(output)
def init_lab(vlab_api, username, wan, switch, config, log): """Initialize the inventory, default networks, and gateway/firewall :Returns: None :param vlab_api: A valid API connection to vLab :type vlab_api: vlab_cli.lib.api.vLabApi :param username: The name of the user deleting their lab :type username: String :param switch: The name of the network switch their networks are connected to :type switch: String :param config: The parsed configuration file used by the vLab CLI :type config: configparser.ConfigParser :param log: A logging object :type log: logging.Logger """ if not config: bad_config = True elif set(config.sections()) != CONFIG_SECTIONS: bad_config = True else: bad_config = False if bad_config: try: new_info = invoke_config() except Exception as doh: log.debug(doh, exc_info=True) raise click.ClickException(doh) else: set_config(new_info) with Spinner('Initializing your lab'): tasks = {} resp1 = vlab_api.post('/api/1/inf/inventory', auto_check=False) tasks['inventory'] = resp1.links['status']['url'] body2 = {'vlan-name': 'frontend', 'switch-name': switch} resp2 = vlab_api.post('/api/2/inf/vlan', json=body2) tasks['frontend_network'] = resp2.links['status']['url'] body3 = {'vlan-name': 'backend', 'switch-name': switch} resp3 = vlab_api.post('/api/2/inf/vlan', json=body3) tasks['backend_network'] = resp3.links['status']['url'] block_on_tasks(vlab_api, tasks, auto_check=False, pause=1) body4 = {'wan': wan, 'lan': 'frontend'.format(username)} consume_task(vlab_api, endpoint='/api/2/inf/gateway', message='Deploying gateway', method='POST', body=body4, timeout=1500, pause=5, auto_check=False) invoke_init_done_help()
def network(ctx, name, switch): """Create a new vLAN network""" body = {'vlan-name': name, 'switch-name': switch} consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/vlan', message='Createing a new network named {}'.format(name), body=body) click.echo('OK!')
def deployment(ctx, name): """Delete a Deployment from your lab""" body = {'template': name} consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/deployment', message='Destroying Deployment {}'.format(name), body=body, method='DELETE') click.echo('OK!')
def router(ctx, name): """Destroy a network router""" body = {'name': '{}'.format(name)} consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/router', message='Destroying network router: {}'.format(name), body=body, method='DELETE') click.echo('OK!')
def network(ctx, name): """Destroy a vLAN network""" if name in ('frontend', 'backend'): click.secho('WARNING: Deleting this network can render your lab unusable', bold=True) click.confirm('Are you sure you wish to continue?', abort=True) body = {'vlan-name': name} consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/vlan', message='Destroying network: {}'.format(name), body=body, method='DELETE') click.echo('OK!')
def avamar(ctx, name): """Delete an Avamar server""" body = {'name': name} consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/avamar/server', message='Destroying Avamar server named {}'.format(name), body=body, method='DELETE') with Spinner('Deleting port mapping rules'): all_ports = ctx.obj.vlab_api.get('/api/1/ipam/portmap', params={'name': name}).json()['content']['ports'] for port in all_ports.keys(): ctx.obj.vlab_api.delete('/api/1/ipam/portmap', json={'conn_port': int(port)}) click.echo('OK!')
def nuke_lab(vlab_api, username, wan, switch, config, log): """Delete all VMs and Networks a user owns, and create a new one. :Returns: None :param vlab_api: A valid API connection to vLab :type vlab_api: vlab_cli.lib.api.vLabApi :param username: The name of the user deleting their lab :type username: String :param switch: The name of the network switch their networks are connected to :type switch: String :param wan: The name of the Wide Area Network their new lab should connect to :type wan: String :param config: The parsed configuration file used by the vLab CLI :type config: configparser.ConfigParser :param log: A logging object :type log: logging.Logger """ consume_task(vlab_api, endpoint='/api/1/inf/power', body={ 'machine': 'all', 'power': 'off' }, message='Powering down your lab', timeout=300, pause=5) consume_task(vlab_api, endpoint='/api/1/inf/inventory', message='Destroying inventory', method='DELETE') resp = consume_task(vlab_api, endpoint='/api/2/inf/vlan', message='Determining what networks you own', method='GET') vlans = resp.json()['content'] tasks = {} with Spinner('Deleting networks'): for vlan in vlans.keys(): resp = vlab_api.delete('/api/2/inf/vlan', json={'vlan-name': vlan}) tasks[vlan] = resp.links['status']['url'] block_on_tasks(vlab_api, tasks, pause=1) typewriter('Finished deleting old lab. Initializing a new lab.') init_lab(vlab_api, username, wan, switch, config=config, log=log)
def router(ctx, image, name, networks): """Create a new network router""" if len(networks) < 2: error = 'Routers must connect at least 2 networks, supplied {}: {}'.format( len(networks), ' '.join(networks)) raise click.ClickException(error) elif len(networks) > 4: error = 'Routers can only connect at most 4 networks, supplied {}: {}'.format( len(networks), ' '.join(networks)) raise click.ClickException(error) body = {'name': name, 'image': image, 'networks': networks} resp = consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/router', message='Creating a new router for networks {}'.format( ' '.join(networks)), body=body, timeout=900, pause=5) data = resp.json()['content'][name] output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) typewriter( "\nUse 'vlab connect router --name {}' to access your new network Router" .format(name))
def icap(ctx, name, protocol): """Connect to an ICAP server""" if protocol == 'console': info = consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/icap', message='Looking up connection info for {}'.format(name), method='GET').json() if not info['content'].get(name, None): error = 'No ICAP VM named {} found'.format(name) raise click.ClickException(error) else: vm_moid = info['content'][name].get('moid', 'n/a') conn = Connectorizer(ctx.obj.vlab_config, gateway_ip='n/a') conn.console(vm_moid) else: target_port = get_protocol_port('icap', protocol) with Spinner('Lookin up connection information for {}'.format(name)): resp = ctx.obj.vlab_api.get('/api/1/ipam/portmap', params={'name' : name, 'target_port' : target_port}).json() try: conn_port = list(resp['content']['ports'].keys())[0] except Exception as doh: ctx.obj.log.debug(doh, exc_info=True) conn_port = None if not conn_port: error = 'No mapping rule for {} to {} exists'.format(protocol, name) raise click.ClickException(error) conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip']) conn.rdp(port=conn_port)
def delete_cluster(vlab_api, cluster): """Destroy an entire OneFS cluster""" data = consume_task(vlab_api, endpoint='/api/2/inf/onefs', message='Looking up OneFS cluster {}'.format(cluster), method='GET').json() nodes = _find_cluster_nodes(cluster, all_nodes=data['content'].keys()) if not nodes: raise click.ClickException('No cluster named {} found'.format(cluster)) tasks = {} with Spinner("Deleting cluster {}".format(cluster)): for node in nodes: body = {'name': node} resp = vlab_api.delete('/api/2/inf/onefs', json=body) tasks[node] = '/api/2/inf/onefs/task/{}'.format( resp.json()['content']['task-id']) block_on_tasks(vlab_api, tasks) with Spinner('Deleting port mapping rules'): for node in nodes: all_ports = vlab_api.get('/api/1/ipam/portmap', params={ 'name': node }).json()['content']['ports'] for port in all_ports.keys(): vlab_api.delete('/api/1/ipam/portmap', json={'conn_port': int(port)}) click.echo('OK!')
def delete_node(vlab_api, name): """Destroy one specific node""" body = {'name': name} consume_task(vlab_api, endpoint='/api/2/inf/onefs', body=body, message='Destroying OneFS node {}'.format(name), method='DELETE') with Spinner('Deleting port mapping rules'): all_ports = vlab_api.get('/api/1/ipam/portmap', params={ 'name': name }).json()['content']['ports'] for port in all_ports.keys(): vlab_api.delete('/api/1/ipam/portmap', json={'conn_port': int(port)}) click.echo('OK!')
def insightiq(ctx, name, image, external_network): """Create an instance of InsightIQ""" body = {'network': external_network, 'name': name, 'image': image} resp = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/insightiq', message='Creating a new instance of InsightIQ running {}'.format( image), body=body, timeout=900, pause=5) data = resp.json()['content'][name] ipv4_addrs = get_ipv4_addrs(data['ips']) if ipv4_addrs: with Spinner("Creating port mapping rules for HTTPS and SSH"): vm_type = data['meta']['component'] https_port = https_to_port(vm_type.lower()) portmap_payload = { 'target_addr': ipv4_addrs[0], 'target_port': https_port, 'target_name': name, 'target_component': 'InsightIQ' } ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) portmap_payload['target_port'] = 22 ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) if ipv4_addrs: typewriter( "\nUse 'vlab connect insightiq --protocol console --name {}' to setup a login password" .format(name)) typewriter("for your new InsightIQ instance.")
def kemp(ctx, name, image, external_network): """Create a Kemp ECS Connection Management load balancer""" body = {'network': external_network, 'name': name, 'image': image} resp = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/kemp', message= 'Creating a new instance of Kemp ECS connection management load balancer running {}' .format(image), body=body, timeout=900, pause=5) data = resp.json()['content'][name] ipv4_addrs = get_ipv4_addrs(data['ips']) if ipv4_addrs: with Spinner("Creating port mapping rules for HTTPS and SSH"): vm_type = data['meta']['component'] https_port = https_to_port(vm_type.lower()) portmap_payload = { 'target_addr': ipv4_addrs[0], 'target_port': https_port, 'target_name': name, 'target_component': data['meta']['component'] } ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) portmap_payload['target_port'] = 22 ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) if ipv4_addrs: typewriter( "\nUse 'vlab connect kemp --protocol console --name {}'".format( name))
def windows(ctx, name, image, external_network): """Create a new Windows Desktop client""" body = {'network': external_network, 'name': name, 'image': image} resp = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/windows', message='Creating a new instance of Windows {}'.format(image), body=body, timeout=900, pause=5) data = resp.json()['content'][name] ipv4_addrs = get_ipv4_addrs(data['ips']) if ipv4_addrs: vm_type = data['meta']['component'] with Spinner('Creating an RDP port mapping rule'): for ipv4 in ipv4_addrs: portmap_payload = { 'target_addr': ipv4, 'target_port': 3389, 'target_name': name, 'target_component': vm_type } ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) if ipv4_addrs: typewriter( "\nUse 'vlab connect windows --name {}' to access your new Windows client" .format(name))
def dd(ctx, name, image, external_network): """Create a Data Domain server""" body = {'network': external_network, 'name': name, 'image': image} resp = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/data-domain', message='Creating a new Data Domain server running {}'.format(image), body=body, timeout=900, pause=5) data = resp.json()['content'][name] ipv4_addrs = get_ipv4_addrs(data['ips']) if ipv4_addrs: with Spinner("Creating port mapping rules for HTTPS and SSH"): vm_type = data['meta']['component'] https_port = https_to_port(vm_type.lower()) portmap_payload = { 'target_addr': ipv4_addrs[0], 'target_port': https_port, 'target_name': name, 'target_component': vm_type } ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) portmap_payload['target_port'] = 22 ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) if ipv4_addrs: typewriter( "\nUse 'vlab connect dd --name {}' to configure your new Data Domain server." .format(name)) typewriter("Initial/default credentials are 'sysadmin' and 'changeme'")
def ana(ctx, name, image, static_ip, external_netmask, default_gateway, dns_servers, domain, external_network): """Create a new Avamar NDMP accelerator.""" body = {'network': external_network, 'name': name, 'image': image, 'ip-config': {'static-ip': static_ip, 'default-gateway': default_gateway, 'netmask': external_netmask, 'dns': dns_servers, 'domain': domain } } resp = consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/avamar/ndmp-accelerator', message='Creating a new Avamar NDMP accelerator running version {}'.format(image), body=body, timeout=1800, pause=5) data = resp.json()['content'][name] vm_type = data['meta']['component'] with Spinner('Creating port mapping rules for HTTPS and SSH'): protocols = get_component_protocols(vm_type.lower()) for protocol in protocols: port = get_protocol_port(vm_type, protocol) payload = {'target_addr' : static_ip, 'target_port' : port, 'target_name' : name, 'target_component' : vm_type} ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=payload) output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) msg = "Use 'vlab connect avamar --name {} --protocol mgmt' to setup your new Avamar Server\n".format(name) msg += "The default credentials are 'root' and 'changme'".format(name) typewriter(msg)
def centos(ctx, name, image, external_network, desktop, cpu_count, ram): """Create an instance of CentOS""" body = {'network': external_network, 'name': name, 'image': image, 'desktop': desktop, 'ram': int(ram), 'cpu-count': int(cpu_count)} resp = consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/centos', message='Creating a new instance of CentOS {}'.format(image), body=body, timeout=900, pause=5) data = resp.json()['content'][name] ipv4_addrs = get_ipv4_addrs(data['ips']) if ipv4_addrs: vm_type = data['meta']['component'] with Spinner('Creating an SSH port mapping rule'): for ipv4 in ipv4_addrs: portmap_payload = {'target_addr' : ipv4, 'target_port' : 22, 'target_name' : name, 'target_component' : vm_type} ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) if desktop: with Spinner('Creating an RDP port mapping rule'): for ipv4 in ipv4_addrs: portmap_payload = {'target_addr' : ipv4, 'target_port' : 3389, 'target_name' : name, 'target_component' : vm_type} ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=portmap_payload) output = format_machine_info(ctx.obj.vlab_api, info=data) click.echo(output) if ipv4_addrs: typewriter("\nUse 'vlab connect centos --name {}' to access your new CentOS instance".format(name))
def gateway(ctx, wan, lan): """Create a network gateway to your virtual lab""" # Network names must be unique. Prefixing the username is a simply hack click.secho('**NOTE**: Gateways can take 10-15 minutes to be created', bold=True) body = {'wan': wan, 'lan': '{}'.format(lan)} resp = consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/gateway', message='Creating a new default gateway', body=body, timeout=900, pause=5) info = resp.json()['content'] shorter_link = ctx.obj.vlab_api.post('/api/1/link', json={'url': info['console']}).json()['content']['url'] ip = [x for x in info['ips'] if not x.startswith('192.168.')] if ip: admin_url = 'https://{}:444'.format(ip[0]) else: admin_url = None rows = [] kind = info['meta']['component'] version = info['meta']['version'] rows.append(['Type', ':', kind]) rows.append(['Version', ':', version]) rows.append(['State', ':', info['state']]) rows.append(['Admin Page', ':', admin_url]) rows.append(['Console', ':', shorter_link]) click.echo(tabulate(rows, tablefmt='plain'))
def portmap(ctx, name, protocol, ip_address): """Create a network port mapping/forwarding rule""" info = consume_task(ctx.obj.vlab_api, endpoint='/api/1/inf/inventory', message='Collecting information about your inventory', method='GET').json() the_vm = info['content'].get(name, None) if the_vm is None: error = "You own no machine named {}. See 'vlab status' for help".format(name) raise click.ClickException(error) vm_type = the_vm['meta']['component'] validate_ip(name, vm_type, the_vm['ips'], ip_address, the_vm['state']) target_addr = determine_which_ip(the_vm['ips'], ip_address) valid_protocols = get_component_protocols(vm_type) if not protocol or protocol not in valid_protocols: protocol = invoke_portmap_clippy(ctx.obj.username, vm_type, valid_protocols) target_port = get_protocol_port(vm_type, protocol) payload = {'target_addr' : target_addr, 'target_port' : target_port, 'target_name' : name, 'target_component' : vm_type} with Spinner('Creating a port mapping rule to {} for {}'.format(name, protocol)): ctx.obj.vlab_api.post('/api/1/ipam/portmap', json=payload) typewriter("OK! Use 'vlab connect {} --name {} --protocol {}' to access that machine".format(vm_type.lower(), name, protocol))
def snapshot(ctx): """Display information about the snapshots in your lab""" info = consume_task(ctx.obj.vlab_api, endpoint='/api/1/inf/snapshot', message='Looking up snapshots in your lab', method='GET').json()['content'] snap_header = ['Component Name', 'Snapshot ID', 'Expiration Date'] rows = [] for vm_name, data in info.items(): row = [] snap_ids = [] exp_dates = [] for snap in data: snap_id = snap['id'] exp_date = epoch_to_date(snap['expires']) snap_ids.append(snap_id) exp_dates.append(exp_date) all_snaps = '\n'.join(snap_ids) rows.append([ vm_name, format_snapinfo(snap_ids), format_snapinfo(exp_dates, default_blank_as='N/A') ]) snap_table = tabulate(rows, headers=snap_header, tablefmt='presto') click.echo('\n{}\n'.format(snap_table))
def router(ctx, name, protocol, user, password): """Connect to the console of a network router""" # Router only supports console access if protocol == 'console': info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/router', message='Looking up connection info for {}'.format(name), method='GET').json() if not info['content'].get(name, None): error = 'No Router named {} found'.format(name) raise click.ClickException(error) else: vm_moid = info['content'][name].get('moid', 'n/a') if password: password_value = getpass.getpass( 'Password for {}: '.format(user)) conn = Connectorizer(ctx.obj.vlab_config, info['content']['gateway_ip'], user=user, password=password_value) else: conn = Connectorizer(ctx.obj.vlab_config, info['content']['gateway_ip'], user=user) conn.console(vm_moid) else: error = 'Unexpected connection protocol supplied' raise click.ClickException(error)
def ecs(ctx, name): """Delete an instance of Elastic Cloud Storage""" body = {'name': name} consume_task(ctx.obj.vlab_api, endpoint='/api/2/inf/ecs', message='Destroying ECS instance named {}'.format(name), body=body, method='DELETE') with Spinner('Deleting port mapping rules'): all_ports = ctx.obj.vlab_api.get('/api/1/ipam/portmap', params={ 'name': name }).json()['content']['ports'] for port in all_ports.keys(): ctx.obj.vlab_api.delete('/api/1/ipam/portmap', json={'conn_port': int(port)}) click.echo('OK!')