Esempio n. 1
0
def down(id=None, lab_name=None):
    """
    stop a lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    lab = None

    if id:
        lab = safe_join_existing_lab(id, client)

    if not lab and lab_name:
        lab = safe_join_existing_lab_by_title(lab_name, client)

    if not lab:
        lab_id = get_current_lab()
        if lab_id:
            lab = safe_join_existing_lab(lab_id, client)

    if lab:
        if lab.is_active():
            click.secho("Shutting down lab {} (ID: {}).....".format(
                lab.title, lab.id))
            lab.stop()
            click.echo(click.style("SUCCESS", fg="green"))
        else:
            click.secho(
                "Lab with ID {} and title {} is already stopped".format(
                    lab.id, lab.title))

    else:
        click.secho("Failed to find lab on server", fg="red")
        exit(1)
Esempio n. 2
0
def save(extract, filename, **kwargs):
    """
    save lab to a local yaml file
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            if extract:
                click.secho("Extracting configurations...")
                extract_configurations(lab)

            lab_export = lab.download()

            click.secho("Writing {}".format(filename))
            with open(filename, "w") as fd:
                fd.write(lab_export)
        else:
            click.secho("Failed to find running lab {}".format(current_lab),
                        fg="red")
            exit(1)
    else:
        click.secho("Current lab is not set", fg="red")
        exit(1)
Esempio n. 3
0
def pyats(**kwargs):
    """
    generates a pyats testbed config for a lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            if kwargs.get("output"):
                # user specified output filename
                file_name = kwargs.get("output")
            else:
                # writes to <lab.id>_testbed.yaml by default
                file_name = "{}_testbed.yaml".format(lab.id)

            testbed = pyats_testbed_generator(lab)

            if testbed:
                click.secho("Writing {}".format(file_name))
                with open(file_name, "w") as fd:
                    fd.write(testbed)
            else:
                click.secho("Failed to get testbed data", fg="red")
                exit(1)
        else:
            click.secho("Failed to find running lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("Current lab is not set", fg="red")
        exit(1)
Esempio n. 4
0
def stop(node):
    """
    stop a node
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            try:
                node_obj = lab.get_node_by_label(node)

                if node_obj.is_active():
                    node_obj.stop(wait=True)
                    click.secho("Stopped node {}".format(node_obj.label))
                else:
                    click.secho("Node {} is already stopped".format(
                        node_obj.label),
                                fg="yellow")
            except NodeNotFound:
                click.secho("Node {} was not found in lab {}".format(
                    node, current_lab),
                            fg="red")
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 5
0
def rm(force, confirm, from_cache):
    """
    remove a lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            if lab.is_active() and force:
                lab.stop(wait=True)

            if lab.state() != "DEFINED_ON_CORE" and force:
                lab.wipe(wait=True)

            # Check again just to be sure.
            if lab.state() == "DEFINED_ON_CORE":
                ret = "y"
                if confirm:
                    ret = input(
                        "Are you sure you want to remove lab {} (ID: {}) [y/N]? "
                        .format(lab.title, current_lab))
                if ret.lower().startswith("y"):
                    # We need to save the lab's title before we remove it.
                    title = lab.title
                    lab.remove()
                    click.secho("Lab {} (ID: {}) removed".format(
                        title, current_lab))
                    if from_cache:
                        try:
                            os.remove(check_lab_cache(current_lab))
                        except OSError:
                            # File doesn't exist.
                            pass

                        click.secho(
                            "Removed lab {} from cache".format(current_lab))
                    clear_current_lab()
                else:
                    click.secho("Not removing lab {} (ID: {})".format(
                        lab.title, current_lab))

            else:
                click.secho(
                    "Lab {} (ID: {}) is either active or not wiped; either down and wipe it or use --force"
                    .format(lab.title, current_lab),
                    fg="red",
                )
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("Current lab is not set", fg="red")
        exit(1)
Esempio n. 6
0
def command(node, command, config, **kwargs):
    """
    send a command or config to a node (requires pyATS)
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            pylab = None
            try:
                pylab = ClPyats(lab)
            except PyatsNotInstalled:
                click.secho("pyATS is not installed, run 'pip install pyats'",
                            fg="red")
                exit(1)

            pyats_username = server.config.get("CML_DEVICE_USERNAME")
            pyats_password = server.config.get("CML_DEVICE_PASSWORD")
            pyats_auth_password = server.config.get(
                "CML_DEVICE_ENABLE_PASSWORD")

            if pyats_username:
                os.environ["PYATS_USERNAME"] = pyats_username
            if pyats_password:
                os.environ["PYATS_PASSWORD"] = pyats_password
            if pyats_auth_password:
                os.environ["PYATS_AUTH_PASS"] = pyats_auth_password

            pylab.sync_testbed(server.user, server.passwd)

            try:
                result = ""
                if config:
                    result = pylab.run_config_command(node, command)
                else:
                    result = pylab.run_command(node, command)

                click.secho(result)
            except PyatsDeviceNotFound:
                click.secho("Node '{}' is not supported by pyATS".format(node),
                            fg="yellow")
            except Exception as e:
                click.secho("Failed to run '{}' on '{}': {}".format(
                    command, node, e))
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 7
0
def ui():
    """
    opens the Workbench for the current lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            url = "https://{}/lab/{}".format(server.host, current_lab)
            subprocess.Popen(["open", url])
Esempio n. 8
0
def ssh(node):
    """
    ssh to a node
    """
    server = VIRLServer()
    client = get_cml_client(server)
    username = server.config.get("VIRL_SSH_USERNAME", "cisco")

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            node_obj = lab.get_node_by_label(node)

            if node_obj:
                if node_obj.is_active():
                    mgmtip = get_node_mgmt_ip(node_obj)
                    if mgmtip:
                        if "VIRL_SSH_COMMAND" in server.config:
                            cmd = server.config["VIRL_SSH_COMMAND"]
                            cmd = cmd.format(host=mgmtip, username=username)
                            print("Calling user specified command: {}".format(
                                cmd))
                            exit(call(cmd.split()))
                        else:
                            click.secho(
                                "Attemping ssh connection to {} at {}".format(
                                    node_obj.label, mgmtip))

                            exit(
                                call(["ssh", "{}@{}".format(username,
                                                            mgmtip)]))
                    else:
                        click.secho(
                            "Node {} does not have an external management IP".
                            format(node_obj.label))
                else:
                    click.secho("Node {} is not active".format(node_obj.label),
                                fg="yellow")
            else:
                click.secho("Node {} was not found in lab {}".format(
                    node, current_lab),
                            fg="red")
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 9
0
def node(node, force, confirm):
    """
    wipe a node
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            node_obj = lab.get_node_by_label(node)

            if node_obj:
                if node_obj.is_active() and force:
                    node_obj.stop()
                    while node_obj.is_active():
                        time.sleep(1)

                if not node_obj.is_active():
                    ret = "y"
                    if confirm:
                        ret = input(
                            "Are you sure you want to wipe node {} [y/N]? ".
                            format(node_obj.label))
                    if ret.lower().startswith("y"):
                        node_obj.wipe(wait=True)
                        click.secho("Node {} wiped".format(node_obj.label))
                    else:
                        click.secho("Not wiping node {}".format(
                            node_obj.label))
                else:
                    click.secho(
                        "Node {} is active; either stop it or use --force".
                        format(node_obj.label),
                        fg="red")
                    exit(1)
            else:
                click.secho("Node {} was not found in lab {}".format(
                    node, current_lab),
                            fg="red")
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 10
0
def check_lab_cache_server(lab_id, client):
    """
    check if a lab exists in either the cache or the server.
    if on server and not in cache, cache the lab.
    """
    ret = None

    if not check_lab_cache(lab_id):
        lab_obj = safe_join_existing_lab(lab_id, client)
        if lab_obj:
            cache_lab(lab_obj)
            ret = lab_id
    else:
        ret = lab_id

    return ret
Esempio n. 11
0
def nso(syncfrom, **kwargs):
    """
    generate nso inventory
    """

    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:

            if kwargs.get("output"):
                file_name = kwargs.get("output")
            else:
                file_name = None

            inv = nso_payload_generator(lab, server)

            if inv:
                if file_name:
                    click.secho("Writing {}".format(file_name))
                    with open(file_name, "w") as fd:
                        fd.write(inv)
                else:
                    click.secho("Updating NSO....")
                    nso_obj = NSO()
                    nso_response = nso_obj.update_devices(inv)
                    if nso_response.ok:
                        click.secho("Successfully added CML devices to NSO")
                    else:
                        click.secho("Error updating NSO: ", fg="red")
                        click.secho(nso_response.text)
                    if syncfrom:
                        resp = nso_obj.perform_sync_from()
                        sync_table(resp.json())
            else:
                click.secho("Failed to get inventory data", fg="red")
                exit(1)
        else:
            click.secho("Failed to find running lab {}".format(current_lab),
                        fg="red")
            exit(1)
    else:
        click.secho("Current lab is not set", fg="red")
        exit(1)
Esempio n. 12
0
def telnet(node):
    """
    telnet to a node
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            try:
                node_obj = lab.get_node_by_label(node)
            except NodeNotFound:
                click.secho("Node {} was not found in lab {}".format(
                    node, current_lab),
                            fg="red")
                exit(1)

            if node_obj.is_active():
                mgmtip = get_node_mgmt_ip(node_obj)
                if mgmtip:
                    if "VIRL_TELNET_COMMAND" in server.config:
                        cmd = server.config["VIRL_TELNET_COMMAND"]
                        cmd = cmd.format(host=mgmtip)
                        print("Calling user specified command: {}".format(cmd))
                        exit(call(cmd.split()))
                    else:
                        click.secho(
                            "Attemping telnet connection to {} at {}".format(
                                node_obj.label, mgmtip))

                        exit(call(["telnet", mgmtip]))
                else:
                    click.secho(
                        "Node {} does not have an external management IP".
                        format(node_obj.label))
            else:
                click.secho("Node {} is not active".format(node_obj.label),
                            fg="yellow")
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 13
0
def nodes():
    """
    get node list for the current lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            node_list_table(lab.nodes())
        else:
            click.secho("Lab {} is not running".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab selected", fg="red")
        exit(1)
Esempio n. 14
0
    def generate(delimiter, output):
        """
        generate generic CSV inventory
        """
        server = VIRLServer()
        client = get_cml_client(server)

        current_lab = get_current_lab()
        if not current_lab:
            click.secho("Current lab is not set", fg="red")
            exit(1)

        lab = safe_join_existing_lab(current_lab, client)
        if not lab:
            click.secho("Failed to find running lab {}".format(current_lab),
                        fg="red")
            exit(1)

        exit(CSVInventory.write_inventory(lab.nodes(), delimiter, output))
Esempio n. 15
0
def lab(force, confirm):
    """
    wipe a lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            active = check_lab_active(lab)
            if active and force:
                lab.stop(wait=True)

            # Check again just to be sure.
            if not check_lab_active(lab):
                ret = "y"
                if confirm:
                    ret = input(
                        "Are you sure you want to wipe lab {} (ID: {}) [y/N]? "
                        .format(lab.title, current_lab))
                if ret.lower().startswith("y"):
                    lab.wipe(wait=True)
                    click.secho("Lab {} (ID: {}) wiped".format(
                        lab.title, current_lab))
                else:
                    click.secho("Not wiping lab {} (ID: {})".format(
                        lab.title, current_lab))

            else:
                click.secho(
                    "Lab {} (ID: {}) is active; either down it or use --force".
                    format(lab.title, current_lab),
                    fg="red")
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 16
0
def extract(update_cache, **kwargs):
    """
    extract configurations from all nodes in a lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            extract_configurations(lab)

            if update_cache:
                cache_lab(lab, force=True)
        else:
            click.secho("Failed to find running lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("Current lab is not set", fg="red")
        exit(1)
Esempio n. 17
0
def ansible(**kwargs):
    """
    generate ansible inventory
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:

            if kwargs.get("output"):
                file_name = kwargs.get("output")
            elif kwargs.get("style") == "ini":
                file_name = "{}_inventory.ini".format(lab.id)
            else:
                file_name = "{}_inventory.yaml".format(lab.id)

            inv = None

            if kwargs.get("style") == "ini":
                inv = ansible_inventory_generator(lab, server, style="ini")
            else:
                inv = ansible_inventory_generator(lab, server)

            if inv:
                click.secho("Writing {}".format(file_name))
                with open(file_name, "w") as fd:
                    fd.write(inv)
            else:
                click.secho("Failed to get inventory data", fg="red")
                exit(1)
        else:
            click.secho("Failed to find running lab {}".format(current_lab),
                        fg="red")
            exit(1)
    else:
        click.secho("Current lab is not set", fg="red")
        exit(1)
Esempio n. 18
0
def command(node, command, config, **kwargs):
    """
    send a command or config to a node (requires pyATS)
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            pylab = None
            try:
                pylab = ClPyats(lab)
            except PyatsNotInstalled:
                click.secho("pyATS is not installed, run 'pip install pyats'", fg="red")
                exit(1)

            pylab.sync_testbed(server.user, server.passwd)

            try:
                result = ""
                if config:
                    result = pylab.run_config_command(node, command)
                else:
                    result = pylab.run_command(node, command)

                click.secho(result)
            except PyatsDeviceNotFound:
                click.secho("Node '{}' is not supported by pyATS".format(node), fg="yellow")
            except Exception as e:
                click.secho("Failed to run '{}' on '{}': {}".format(command, node, e))
                exit(1)
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)
Esempio n. 19
0
    def run(new_title):
        """
        re-title the current lab
        """

        server = VIRLServer()
        client = get_cml_client(server)

        clab = get_current_lab()

        if not clab:
            click.secho("Current lab is not set", fg="red")
            exit(1)

        lab = safe_join_existing_lab(clab, client)
        if lab:
            lab.title = new_title
        else:
            click.secho(
                "Current lab {} is not present on the server".format(clab),
                fg="red")
            exit(1)
Esempio n. 20
0
def nodes():
    """
    get node list for the current lab
    """
    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            try:
                pl = ViewerPlugin(viewer="node")
                pl.visualize(nodes=lab.nodes())
            except NoPluginError:
                node_list_table(lab.nodes())
        else:
            click.secho("Lab {} is not running".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab selected", fg="red")
        exit(1)
Esempio n. 21
0
def lid():
    """
    get the current lab title and ID
    """
    server = VIRLServer()
    client = get_cml_client(server)
    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        # The lab really should be on the server.
        if not lab:
            try:
                lab = CachedLab(current_lab, get_current_lab_link())
            except Exception:
                pass

        if lab:
            click.echo("{} (ID: {})".format(lab.title, current_lab))
        else:
            click.secho(
                "Current lab is set to {}, but is not on server or in cache!".
                format(current_lab),
                fg="red")
Esempio n. 22
0
def up(repo=None, provision=False, start=True, **kwargs):
    """
    start a lab
    """
    def_fname = kwargs["f"]
    alt_fname = "topology.virl"
    fname = def_fname
    lid = kwargs["id"]
    lab_name = kwargs["lab_name"]
    lab = None
    clab = None

    server = VIRLServer()
    client = get_cml_client(server)

    current_lab = get_current_lab()
    if current_lab:
        clab = safe_join_existing_lab(current_lab, client)
        if not clab:
            click.secho(
                "Current lab is already set to {}, but that lab is not on server; clearing it."
                .format(current_lab),
                fg="yellow")
            clear_current_lab()

    if not clab or fname or lid or lab_name:
        if clab:
            click.secho(
                "WARNING: Current lab is set to {} (ID: {}); clearing it".
                format(clab.title, current_lab),
                fg="yellow")
            clear_current_lab()

        if not def_fname:
            def_fname = "topology.yaml"
            fname = def_fname

        if not os.path.isfile(def_fname) and os.path.isfile(alt_fname):
            fname = alt_fname

        if lid:
            lab = safe_join_existing_lab(lid, client)
            if not lab:
                # Check the cache
                existing = check_lab_cache(lid)
                if existing:
                    fname = existing

        if not lab and lab_name:
            lab = safe_join_existing_lab_by_title(lab_name, client)

        if not lab and os.path.isfile(fname):
            lname = get_lab_title(fname)
            click.secho("Importing lab {} from file {}".format(lname, fname))
            lab = client.import_lab_from_path(fname, title=lname)
        elif not lab:
            # try to pull from virlfiles
            if repo and os.path.basename(fname) == "topology.yaml":
                rc = call([get_command(), "pull", repo])
                if rc == 0:
                    exit(call([get_command(), "up"]))

        if lab:
            if lab.is_active():
                cache_lab(lab)
                set_current_lab(lab.id)
                click.secho(
                    "Lab is already running (ID: {}, Title: {})".format(
                        lab.id, lab.title))
            elif start:
                start_lab(lab, provision)

        else:
            click.secho("Could not find a lab to start.  Maybe try -f",
                        fg="red")
            exit(1)
    elif clab:
        click.secho("Lab {} (ID: {}) is already set as the current lab".format(
            clab.title, current_lab))
        if not clab.is_active() and start:
            start_lab(clab, provision)
Esempio n. 23
0
def console(node, display, **kwargs):
    """
    console for node
    """
    server = VIRLServer()
    client = get_cml_client(server)
    skip_types = ["external_connector", "unmanaged_switch"]

    current_lab = get_current_lab()
    if current_lab:
        lab = safe_join_existing_lab(current_lab, client)
        if lab:
            try:
                node_obj = lab.get_node_by_label(node)
            except NodeNotFound:
                click.secho("Node {} was not found in lab {}".format(
                    node, current_lab),
                            fg="red")
                exit(1)

            if node_obj.node_definition not in skip_types:
                if node_obj.is_active():
                    console = "/{}/{}/0".format(lab.id, node_obj.id)
                    if display:
                        console_table([{"node": node, "console": console}])
                    else:
                        # use user specified ssh command
                        if "CML_CONSOLE_COMMAND" in server.config:
                            cmd = server.config["CML_CONSOLE_COMMAND"]
                            cmd = cmd.format(host=server.host,
                                             user=server.user,
                                             console="open " + console)
                            print("Calling user specified command: {}".format(
                                cmd))
                            exit(call(cmd.split()))

                        # someone still uses windows
                        elif platform.system() == "Windows":
                            with helpers.disable_file_system_redirection():
                                cmd = "ssh -t {}@{} open {}".format(
                                    server.user, server.host, console)
                                exit(call(cmd.split()))

                        # why is shit so complicated?
                        else:
                            cmd = "ssh -t {}@{} open {}".format(
                                server.user, server.host, console)
                            exit(call(cmd.split()))
                else:
                    click.secho("Node {} is not active".format(node), fg="red")
                    exit(1)
            else:
                click.secho(
                    "Node type {} does not support console connectivity".
                    format(node_obj.node_definition),
                    fg="yellow")
        else:
            click.secho("Unable to find lab {}".format(current_lab), fg="red")
            exit(1)
    else:
        click.secho("No current lab set", fg="red")
        exit(1)