예제 #1
0
파일: centos.py 프로젝트: willnx/vlab_cli
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))
예제 #2
0
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!')
예제 #3
0
파일: portmap.py 프로젝트: willnx/vlab_cli
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))
예제 #4
0
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'")
예제 #5
0
파일: windows.py 프로젝트: willnx/vlab_cli
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))
예제 #6
0
파일: portmap.py 프로젝트: willnx/vlab_cli
def portmap(ctx, verbose):
    """Display configured port mapping/forwarding rules"""
    table = "No portmap rules exist"
    with Spinner('Looking up port mapping rules'):
        data = ctx.obj.vlab_api.get('/api/1/ipam/portmap').json()['content']
        rules = data['ports']
        gateway_ip = data['gateway_ip']
        header = ['Name', 'Type', 'Port', 'Protocol']
        if verbose:
            header.append('Target IP')
        rows = []
        for conn_port, details in rules.items():
            name = details.get('name', 'Error')
            vm_type = details.get('component', 'Unknown')
            vm_port = details.get('target_port', 0)
            protocol = port_to_protocol(vm_type, vm_port)
            target_ip = details.get('target_addr', 'Unknown')
            if verbose:
                row = [name, vm_type, conn_port, protocol, target_ip]
            else:
                row = [name, vm_type, conn_port, protocol]
            rows.append(row)
            table = tabulate(rows,
                             headers=header,
                             tablefmt='presto',
                             numalign="center")
    click.echo('\nGateway IP: {}'.format(gateway_ip))
    click.echo(table)
예제 #7
0
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)
예제 #8
0
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)
예제 #9
0
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.")
예제 #10
0
파일: kemp.py 프로젝트: willnx/vlab_cli
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))
예제 #11
0
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)
예제 #12
0
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()
예제 #13
0
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)
예제 #14
0
파일: api.py 프로젝트: willnx/vlab_cli
def consume_task(vlab_api,
                 endpoint,
                 message,
                 method='POST',
                 body=None,
                 params=None,
                 timeout=60,
                 pause=1,
                 auto_check=True,
                 base_endpoint=True):
    """Automates processing tasks issued by the vLab API

    :Returns: requests.Response

    :param vlab_api: A valid API connection to vLab
    :type vlab_api: vlab_cli.lib.api.vLabApi

    :param endpoint: The URL that issued the task
    :type endpoint: String

    :param message: What to tell the end user while waiting on the task
    :type message: String

    :param timeout: How long to wait for the task to complete. Default 60 seconds
    :type timeout: Integer

    :param pause: How long to wait in between checking on the status of the task.
    :type pause: Integer

    :param auto_check: Check the response code, and if needed raise an exception
    :type auto_check: Boolean

    :param base_endpoint: Set to False if the end point is for <base>/image
    :type base_endpoint: Boolean
    """
    with Spinner(message):
        resp = vlab_api._call(method=method.lower(),
                              endpoint=endpoint,
                              auto_check=auto_check,
                              json=body,
                              params=params)
        task = resp.json()['content']['task-id']
        if base_endpoint:
            url = '{}/task/{}'.format(endpoint, task)
        else:
            url = resp.links['status']['url']
        for _ in range(0, timeout, pause):
            resp = vlab_api.get(url, auto_check=auto_check)
            if resp.status_code == 202:
                time.sleep(pause)
            else:
                break
        else:
            error = 'Timed out on task {}'.format(task)
            raise click.ClickException(error)
        return resp
예제 #15
0
파일: connect.py 프로젝트: willnx/vlab_cli
def invoke_config():
    """Initial config setup help"""
    the_os = platform.system().lower()
    typewriter("In order for 'vlab connect' to work, you'll need to have a")
    typewriter("browser, an SSH client, an SCP client and the VMware Remote Client (VMRC) installed.")
    typewriter("Based on your OS, I can use the following:")
    typewriter(", ".join(configurizer.SUPPORTED_PROGS))
    if the_os == 'windows':
        typewriter("\nNote: 'wt' is short for Windows Terminal, which also requires 'ssh' to be installed.")
        typewriter("Note: mstsc is the default RDP client that comes with Windows")

    typewriter('\nIf you do not have the SSH, RDP, SCP and VMRC clients as well as a supported browser')
    typewriter("installed you'll be wasting time by continuing with this config setup.")
    keep_going = prompt("Continue with config setup? [Yes/no]", boolean=True, boolean_default=True)
    if not keep_going:
        raise RuntimeError("vlab connect prerequisites not met")
    with Spinner('Great! Give me a couple of minutes to find those programs'):
        found_programs = configurizer.find_programs()
        firefox = found_programs.get('firefox', '')
        chrome = found_programs.get('chrome', '')
        putty = found_programs.get('putty', '')
        secure_crt = found_programs.get('securecrt', '').lower()
        windows_term = found_programs.get('wt', '')
        winscp = found_programs.get('winscp', '').lower()
        filezilla = found_programs.get('filezilla', '')
        scp = found_programs.get('scp', '')

    browsers = [x for x in [firefox, chrome] if x]
    if firefox and chrome:
        forget_browsers = which_client(browsers, 'Browser')
        for browser in forget_browsers:
            found_programs.pop(browser)

    scp_clients = [x for x in [winscp, filezilla, scp] if x]
    if len(scp_clients) > 1:
        forget_scp = which_client(scp_clients, 'SCP')
        for scp_client in forget_scp:
            found_programs.pop(scp_client)

    ssh_clients = [x for x in [putty, secure_crt, windows_term] if x]
    if len(ssh_clients) > 1:
        forget_ssh_clients = which_client(ssh_clients, 'SSH')
        for ssh_client in forget_ssh_clients:
            found_programs.pop(ssh_client)

    if len(found_programs) != 5:
        # They are missing some dependency...
        if the_os == 'windows':
            scanned_drive = 'C:\\'
        else:
            scanned_drive = '/ (i.e. root)'
        typewriter("\nUh oh, there's a problem. I wasn't able to find everything under {}.".format(scanned_drive))
        typewriter("Here are the programs I was able to locate:\n\t{}".format(' '.join(found_programs.keys())))
        typewriter("Please install the missing software, then re-run the 'vlab init' command.")
        raise click.ClickException('Missing required dependencies')
    return _make_config(found_programs)
예제 #16
0
파일: portmap.py 프로젝트: willnx/vlab_cli
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!')
예제 #17
0
def deployment(ctx, name, protocol, user, password):
    """Connect to a deployed machine"""
    if protocol == 'console':
        info = consume_task(
            ctx.obj.vlab_api,
            endpoint='/api/2/inf/deployment',
            message='Looking up connection info for {}'.format(name),
            method='GET').json()
        if not info['content'].get(name, None):
            error = 'No Deployment 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:
        with Spinner('Looking up connection information for {}'.format(name)):
            data = ctx.obj.vlab_api.get('/api/1/ipam/portmap',
                                        params={
                                            'name': name
                                        }).json()['content']
            ports = data['ports']
            port_map = {ports[x]['target_port']: x for x in ports.keys()}
            try:
                conn_port = determine_port(protocol, port_map)
            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,
                                 data['gateway_ip'],
                                 user=user,
                                 password=password_value)
        else:
            conn = Connectorizer(ctx.obj.vlab_config,
                                 data['gateway_ip'],
                                 user=user)
        if protocol == 'ssh':
            conn.ssh(port=conn_port)
        elif protocol == 'scp':
            conn.scp(port=conn_port)
        elif protocol == 'rdp':
            conn.rdp(port=conn_port)
        elif protocol == 'https':
            conn.https(port=conn_port)
        else:
            error = 'Unexpected protocol requested: {}'.format(protocol)
            raise RuntimeError(error)
예제 #18
0
파일: dataiq.py 프로젝트: willnx/vlab_cli
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))
예제 #19
0
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)
예제 #20
0
파일: avamar.py 프로젝트: willnx/vlab_cli
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!')
예제 #21
0
def superna(ctx, name, protocol, user, password):
    """Connect to an Superna Eyeglass server"""
    if protocol == 'console':
        info = consume_task(
            ctx.obj.vlab_api,
            endpoint='/api/2/inf/superna',
            message='Looking up connection info for {}'.format(name),
            method='GET').json()
        if not info['content'].get(name, None):
            error = 'No Data Domain 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:
        if protocol.lower() == 'https':
            error = 'Superna web interface only accessible from a machine *inside* your lab.'
            raise click.ClickException(error)
        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 == 'scp':
            conn.scp(port=conn_port)
        else:
            error = 'Unexpected protocol requested: {}'.format(protocol)
            raise RuntimeError(error)
예제 #22
0
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)
예제 #23
0
def map_ips(vlab_api, nodes, ip_range):
    """Create the port mapping rules for each node"""
    low_ip = str(min([ipaddress.ip_address(x) for x in ip_range]))
    high_ip = str(max([ipaddress.ip_address(x) for x in ip_range]))
    ips = _generate_ips(low_ip, high_ip)
    https_port = https_to_port('onefs')
    with Spinner('Creating SSH and HTTPS mapping rules for each node'):
        for ip, node in zip(ips, nodes):
            portmap_payload = {'target_addr': ip,
                               'target_port': https_port,
                               'target_name': node,
                               'target_component' : 'OneFS'}
            vlab_api.post('/api/1/ipam/portmap', json=portmap_payload)
            portmap_payload['target_port'] = 22
            vlab_api.post('/api/1/ipam/portmap', json=portmap_payload)
예제 #24
0
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!')
예제 #25
0
파일: dns.py 프로젝트: willnx/vlab_cli
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]))
예제 #26
0
def claritynow(ctx, name, image, external_network):
    """Create an instance of ClarityNow"""
    body = {'network': external_network, 'name': name, 'image': image}
    resp = consume_task(
        ctx.obj.vlab_api,
        endpoint='/api/2/inf/claritynow',
        message='Creating a new instance of ClarityNow {}'.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']
        https_port = https_to_port(vm_type.lower())
        with Spinner('Creating an SSH, RDP, and HTTPS port mapping rules'):
            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)

                portmap_payload['target_port'] = 3389
                ctx.obj.vlab_api.post('/api/1/ipam/portmap',
                                      json=portmap_payload)

                portmap_payload['target_port'] = https_port
                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)
    info = """\n    ***IMPORTANT***

    ClarityNow requires a valid license to operate.
    Your ClarityNow server license will expire in 60 days.
    """
    click.secho(info, bold=True)
    if ipv4_addrs:
        typewriter(
            "Use 'vlab connect claritynow --name {}' to access your new ClarityNow instance"
            .format(name))
예제 #27
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)
예제 #28
0
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!')
예제 #29
0
def create_nodes(username, name, image, external, internal, node_count, ram, cpu_count, vlab_api):
    """Concurrently make all nodes

    :Returns: Dictionary

    :param username: The user who owns the new nodes
    :type username: String

    :param image: The image/version of OneFS node to create
    :type image: String

    :param external: The base name of the external network to connect the node(s) to
    :type external: String

    :param internal: The base name of the internal network to connect the node(s) to
    :type external: String

    :param node_count: The number of OneFS nodes to make
    :type node_count: Integer

    :param ram: The number of GB of ram/memory to create a OneFS node with
    :type ram: Integer

    :param cpu_count: The number of CPU cores to allocate to the vOneFS node
    :type cpu_count: Integer

    :param vlab_api: An instantiated connection to the vLab server
    :type vlab_api: vlab_cli.lib.api.vLabApi
    """
    tasks = {}
    node_v_nodes = 'node' if node_count == 1 else 'nodes'
    with Spinner('Deploying {} {} running {}'.format(node_count, node_v_nodes, image)):
        for idx in range(node_count):
            node_name = '{}-{}'.format(name, idx +1) # +1 so we don't have node-0
            body = {'name' : node_name,
                    'image': image,
                    'frontend': external,
                    'backend': internal,
                    'ram': ram,
                    'cpu-count': cpu_count,
                    }
            resp = vlab_api.post('/api/2/inf/onefs', json=body)
            tasks[node_name] = '/api/2/inf/onefs/task/{}'.format(resp.json()['content']['task-id'])
        info = block_on_tasks(vlab_api, tasks)
    return info
예제 #30
0
파일: icap.py 프로젝트: willnx/vlab_cli
def icap(ctx, name, image, external_network):
    """Create an ICAP Antivirus server"""
    body = {'network': external_network, 'name': name, 'image': image}
    resp = consume_task(
        ctx.obj.vlab_api,
        endpoint='/api/2/inf/icap',
        message='Creating a new ICAP server running version {}'.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)
        ip_addr = ipv4_addrs[0]
    else:
        ip_addr = 'ERROR'

    output = format_machine_info(ctx.obj.vlab_api, info=data)
    click.echo(output)
    note = """\n    ***IMPORTANT***

    Before you can use your ICAP sever you must configure the IP the service listens on.
    To configure this, please open the console and:

    1) Launch the McAfee admin panel (look at the task bar)
    2) Right click on the ICAP service, and select "properties"
    3) Update the IP to {}
    4) Remember to click "OK" to save the setting
    """.format(ip_addr)
    click.secho(note, bold=True)
    if ipv4_addrs:
        typewriter(
            "Use 'vlab connect icap --name {}' to access your new ICAP server".
            format(name))