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 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 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 avamar(ctx, name, protocol, user, password): """Connect to an Avamar server""" if protocol == 'console': info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/avamar/server', message='Looking up connection info for {}'.format(name), method='GET').json() if not info['content'].get(name, None): error = 'No Avamar server 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('Avamar', 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) if password: password_value = getpass.getpass('Password for {}: '.format(user)) conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip'], user=user, password=password_value) else: conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip'], user=user) if protocol == 'ssh': conn.ssh(port=conn_port) elif protocol == 'https': click.secho( "WARNING: Some parts of the Avamar WebUI only work from inside your lab.", bold=True) conn.https(port=conn_port, endpoint='/dtlt/home.html') elif protocol == 'scp': conn.scp(port=conn_port) elif protocol == 'mgmt': conn.https(port=conn_port) else: error = 'Unexpected protocol requested: {}'.format(protocol) raise RuntimeError(error)
def portmap(ctx, name, protocol, ip_address, override_port): """Destroy a port mapping rule""" if ip_address and override_port: target_port = 0 protocol = 'an unknown protocol' else: 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'], action='delete') 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) # Part of the fix for https://github.com/willnx/vlab/issues/61 # This chunk of code allows users to delete port mapping rules # for the bad/wrong ESRS port. if the_vm['meta']['component'].lower() == 'esrs' and override_port: target_port = override_port with Spinner('Deleting port mapping rule to {} for {}'.format( name, protocol)): resp = ctx.obj.vlab_api.get('/api/1/ipam/portmap', params={ 'name': name, 'target_port': target_port }).json() try: if not override_port: conn_port = list(resp['content']['ports'].keys())[0] else: conn_port = override_port except IndexError: # No such rule, but who cares? The target state (i.e. no rule) is true pass else: ctx.obj.vlab_api.delete('/api/1/ipam/portmap', json={'conn_port': int(conn_port)}) click.echo('OK!')
def dataiq(ctx, name, image, external_network, external_netmask, default_gateway, dns_servers, static_ip, disk_size, cpu_count, ram): """Create an instance of DataIQ""" error = network_config_ok(static_ip, default_gateway, external_netmask) if error: raise click.ClickException(error) body = { 'network': external_network, 'name': name, 'image': image, 'static-ip': static_ip, 'default-gateway': default_gateway, 'external-netmask': external_netmask, 'dns-servers': dns_servers, 'disk-size': int(disk_size), 'cpu-count': int(cpu_count), 'ram': int(ram) } resp = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/dataiq', message='Creating a new instance of DataIQ {}'.format(image), body=body, timeout=1800, pause=5) data = resp.json()['content'][name] data['ips'] = [static_ip] vm_type = data['meta']['component'] protocols = get_component_protocols(vm_type.lower()) with Spinner('Creating port mapping rules for SSH, HTTPS, and RDP'): for protocol in protocols: target_port = get_protocol_port(vm_type.lower(), protocol) portmap_payload = { 'target_addr': static_ip, 'target_port': target_port, '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) message = """\n ***IMPORTANT*** DataIQ still needs to be installed on your new instance. Please refer to the DataIQ Admin guide for installation directions: https://www.dell.com/support/home/us/en/19/product-support/product/data-iq/docs """ click.secho(message, bold=True) typewriter( "\nUse 'vlab connect dataiq --name {}' to access your new DataIQ instance" .format(name))
def kemp(ctx, name, protocol, user, password): """Connect to a Kemp ECS Connection Management load balancer""" if protocol == 'console': info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/kemp', message='Looking up connection info for {}'.format(name), method='GET').json() if not info['content'].get(name, None): error = 'No Kemp ECS Connection Management load balancer 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('insightiq', 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) if password: password_value = getpass.getpass('Password for {}: '.format(user)) conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip'], user=user, password=password_value) else: conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip'], user=user) if protocol == 'ssh': conn.ssh(port=conn_port) elif protocol == 'https': conn.https(port=conn_port) elif protocol == 'scp': conn.scp(port=conn_port) else: error = 'Unexpected protocol requested: {}'.format(protocol) raise RuntimeError(error)
def dns(ctx, name, image, external_network, external_netmask, default_gateway, dns_servers, static_ip): """Create a DNS server""" error = network_config_ok(static_ip, default_gateway, external_netmask) if error: raise click.ClickException(error) body = { 'network': external_network, 'name': name, 'image': image, 'static-ip': static_ip, 'default-gateway': default_gateway, 'external-netmask': external_netmask, 'dns-servers': dns_servers } resp = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/dns', message='Creating a new DNS server running {}'.format(image), body=body, timeout=1800, pause=5) data = resp.json()['content'][name] data['ips'] = [static_ip] vm_type = data['meta']['component'] if image.lower().startswith('windows'): protocols = ['rdp'] else: protocols = ['ssh'] with Spinner('Creating a port mapping rule for {}'.format( protocols[0].upper())): for protocol in protocols: target_port = get_protocol_port(vm_type.lower(), protocol) portmap_payload = { 'target_addr': static_ip, 'target_port': target_port, '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) typewriter( "\nUse 'vlab connect dns --name {} --protocol {}' to access your new dns instance" .format(name, protocols[0]))
def dataiq(ctx, name, protocol): """Connect to a DataIQ instance""" if protocol == 'console': info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/dataiq', message='Looking up connection info for {}'.format(name), method='GET').json() if not info['content'].get(name, None): error = 'No dataiq 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('dataiq', 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']) if protocol == 'ssh': conn.ssh(port=conn_port) elif protocol == 'https': conn.https(port=conn_port) elif protocol == 'scp': conn.scp(port=conn_port) elif protocol == 'rdp': conn.rdp(port=conn_port) else: error = 'Unexpected protocol requested: {}'.format(protocol) raise RuntimeError(error)
def winserver(ctx, name, protocol, user, password): """Connect to a Microsoft Server instance""" if protocol == 'console': info = consume_task( ctx.obj.vlab_api, endpoint='/api/2/inf/winserver', message='Looking up connection info for {}'.format(name), method='GET').json() if not info['content'].get(name, None): error = 'No Windows Server 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('winserver', 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) if password: password_value = getpass.getpass('Password for {}: '.format(user)) conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip'], user=user, password=password_value) else: conn = Connectorizer(ctx.obj.vlab_config, resp['content']['gateway_ip'], user=user) conn.rdp(port=conn_port)