コード例 #1
0
def get_testbed(lab, host, user, passwd):
    client_library = ClientLibrary("https://" + host,
                                   user,
                                   passwd,
                                   ssl_verify=False)
    lab = client_library.join_existing_lab(args.lab)
    return lab.get_pyats_testbed()
コード例 #2
0
ファイル: test_connect.py プロジェクト: xorrkaz/virl2-client
def test_connect(client_library: ClientLibrary):
    lab = client_library.create_lab("my lab name")
    lab = client_library.join_existing_lab(lab.id)

    lab.auto_sync = False

    s1 = lab.create_node("s1", "server", 50, 100)
    s2 = lab.create_node("s2", "server", 50, 200)
    print(s1, s2)

    # create a link between s1 and s2
    s1_i1 = s1.create_interface()
    s2_i1 = s2.create_interface()
    lab.create_link(s1_i1, s2_i1)

    # this must remove the link between s1 and s2
    lab.remove_node(s2)

    lab.sync_states()
    for node in lab.nodes():
        print(node, node.state)
        for iface in node.interfaces():
            print(iface, iface.state)

    assert [link for link in lab.links() if link.state is not None] == []
コード例 #3
0
def stop_wipe_and_remove_all_labs(client_library: ClientLibrary):
    lab_list = client_library.get_lab_list()
    for lab_id in lab_list:
        lab = client_library.join_existing_lab(lab_id)
        lab.stop()
        lab.wipe()
        client_library.remove_lab(lab_id)
コード例 #4
0
def test_sync_lab(register_licensing, client_library: ClientLibrary):
    lab = client_library.create_lab("my test lab name")
    lab = client_library.join_existing_lab(lab.id)

    r1 = lab.create_node("r1", "server", 5, 100)
    r2 = lab.create_node("r2", "server", 102, 201)
    r3 = lab.create_node("r3", "server", 200, 400)
    # print(r1, r2, r3)

    r1.x = 400
    r1.label = "abc"

    r1_i1 = r1.create_interface()
    r1_i2 = r1.create_interface()

    r2_i1 = r2.create_interface()
    r2_i2 = r2.create_interface()

    r3_i1 = r3.create_interface()
    r3_i2 = r3.create_interface()

    #
    lab.create_link(r1_i1, r2_i1)
    lab.create_link(r2_i2, r3_i1)
    lab.create_link(r3_i2, r1_i2)

    r1.start()
    r2.start()
    r3.start()

    # lab.stop()
    r1.stop()
    r2.stop()
    r3.stop()

    # lab.remove_link(link_1)
    # lab.remove_link(link_2)
    # lab.remove_link(link_3)
    # lab.remove_node(r1)
    # lab.remove_node(r2)
    # lab.remove_node(r3)

    # TODO: wait for convergence here
    lab.stop()
コード例 #5
0
    def lab_download(self):
        """
        Imports an existing topology from a CML2 server. Downloaded configuration is stored in self.lab_conf class
        variable and parsed as YAML object

        :raises TypeError: if no lab_id is provided
        :raises requests.exceptions.HTTPError: if there was a transport error
        """

        cl = ClientLibrary(url="https://" + self._cmlnetkitconfig.host,
                           username=self._cmlnetkitconfig.username,
                           password=self._cmlnetkitconfig.password,
                           ssl_verify=self._cmlnetkitconfig.ssl_verify)
        cl.wait_for_lld_connected()
        try:
            self.lab_handler = cl.join_existing_lab(
                self._cmlnetkitconfig.lab_id)
            self.lab_conf = yaml.safe_load(self.lab_handler.download())
        except TypeError:
            print(
                "TypeError: No lab_id provided. Use the -l option to provide the lab_id"
            )
コード例 #6
0
LAB_NAME = input("enter lab name: ")

client = ClientLibrary(VIRL_CONTROLLER,
                       VIRL_USERNAME,
                       VIRL_PASSWORD,
                       ssl_verify=False)

# Find the lab by title and join it as long as it's the only
# lab with that title.
labs = client.find_labs_by_title(LAB_NAME)

if not labs or len(labs) != 1:
    print("ERROR: Unable to find a unique lab named {}".format(LAB_NAME))
    exit(1)

lobj = client.join_existing_lab(labs[0].id)

if not lobj:
    print("ERROR: Failed to join lab {}".format(LAB_NAME))
    exit(1)

# Print all links in the lab and ask which link to condition.
i = 1
liobjs = []
for link in lobj.links():
    print("{}. {}[{}] <-> {}[{}]".format(
        i,
        link.interface_a.node.label,
        link.interface_a.label,
        link.interface_b.node.label,
        link.interface_b.label,
コード例 #7
0
# setup the connection and clean everything
cl = ClientLibrary("http://localhost:8001", "cml2", "cml2cml2", allow_http=True)
cl.is_system_ready(wait=True)

# set transport if needed - also proxy can be set if needed
# cl.licensing.licensing.set_transport(ssms=ssms, proxy_server="172.16.1.100", proxy_port=8888)
cl.licensing.set_transport(ssms=SSMS)
cl.licensing.install_certificate(cert=CERT)
# 'register_wait' method waits max 45s for registration status to become COMPLETED
# and another 45s for authorization status to become IN_COMPLIANCE
cl.licensing.register_wait(token=TOKEN)


lab_list = cl.get_lab_list()
for lab_id in lab_list:
    lab = cl.join_existing_lab(lab_id)
    lab.stop()
    lab.wipe()
    cl.remove_lab(lab_id)

lab = cl.create_lab()
lab = cl.join_existing_lab(lab_id="lab_1")

s1 = lab.create_node("s1", "server", 50, 100)
s2 = lab.create_node("s2", "server", 50, 200)
print(s1, s2)

# create a link between s1 and s2, equivalent to
#   s1_i1 = s1.create_interface()
#   s2_i1 = s2.create_interface()
#   lab.create_link(s1_i1, s2_i1)
コード例 #8
0
class CML(object):
    def __init__(self, host, username, password):
        logger = logging.getLogger("virl2_client.virl2_client")
        level = logger.getEffectiveLevel()
        logger.setLevel(logging.ERROR)

        # Remove VIRL2 envvars if they exist.  These would conflict with the virlutils config.
        os.environ.pop("VIRL2_USER", None)
        os.environ.pop("VIRL2_PASS", None)
        os.environ.pop("VIRL2_URL", None)

        self._host = host
        self._username = username
        self._password = password
        self._consoles = {}
        self._student = None
        self._student_password = None
        self._student_name = None

        self._client = ClientLibrary(host,
                                     username,
                                     password,
                                     raise_for_auth_failure=True,
                                     ssl_verify=False)
        logger.setLevel(level)

    def import_lab(self, filename, title):
        lab = self._client.import_lab_from_path(filename, title=title)
        return lab.id

    def configure_lab(self, lid, student, name, passwd, cfg_dir):
        self._student = student
        self._student_password = passwd
        self._student_name = name
        lab = self._client.join_existing_lab(lid)
        for node in lab.nodes():
            if node.label == "jump-host":
                continue
            nconfig = cfg_dir + "/" + node.label + ".cfg"
            if os.path.isfile(nconfig):
                with open(nconfig, "r") as fd:
                    node.config = fd.read()

    def _configure_breakout(self, lab):
        jump_host = lab.get_node_by_label("jump-host")
        config = f"""\
#cloud-config
password: cisco
chpasswd: {{ expire: False }}
hostname: jump-host
ssh_pwauth: True
users:
    - default
    - name: {self._student}
      gecos: {self._student_name}
      plain_text_passwd: '{self._student_password}'
      lock_passwd: false
      password: '******'
      shell: /bin/bash
write_files:
    - content: |
        console_start_port: {CONSOLE_BASE_PORT}
        controller: https://{self._host}
        username: {self._student}
        password: '******'
        populate_all: false
        verify_tls: false
        listen_address: '0.0.0.0'
      path: /etc/breakout/config.yaml
    - content: |
        {lab.id}:
            enabled: true
            lab_description: ""
            lab_title: {lab.title}
            nodes:
"""
        base_port = CONSOLE_BASE_PORT
        i = 0
        ignore_nodes = ["jump-host", "Mgmt-net"]
        for node in lab.nodes():
            if node.label in ignore_nodes or node.node_definition == "external_connector":
                continue

            self._consoles[node.label] = base_port + i
            config += f"""
                {node.id}:
                    devices:
                        - enabled: true
                          listen_port: {self._consoles[node.label]}
                          name: serial0
                          running: true
                          status: ""
                    label: {node.label}
"""
            i += 1
        config += f"""
      path: /etc/breakout/labs.yaml
    - content: |
        #!/bin/bash

        nohup /usr/bin/cml_breakout -config /etc/breakout/config.yaml -extralf -labs /etc/breakout/labs.yaml -listen 0.0.0.0 -noverify run &
      path: /etc/breakout/breakout.sh
      permissions: '0755'
runcmd:
    - [ ip, addr, add, 192.168.1.1/24, dev, ens3 ]
    - [ ip, link, set, up, dev, ens3 ]
    - [ curl, -L, --output, /usr/bin/cml_breakout, -k, 'https://{self._host}/breakout/breakout-linux-x86_amd64' ]
    - [ chmod, '0555', /usr/bin/cml_breakout ]
    - [ /etc/breakout/breakout.sh ]
"""
        jump_host.config = config

    def start_lab(self, lid):
        lab = self._client.join_existing_lab(lid)
        mnets = []
        for node in lab.nodes():
            if node.label != "jump-host":
                node.start()

            if node.node_definition == "external_connector":
                mnets.append(node)

        if len(mnets) > 0:
            ready = False
            while not ready:
                for n in mnets:
                    if not n.is_booted():
                        ready = False
                        break
                    ready = True
                time.sleep(1)

        self._configure_breakout(lab)
        jump_host = lab.get_node_by_label("jump-host")
        jump_host.start()
        while not jump_host.is_booted():
            time.sleep(1)

    def get_lab_address(self, lid):
        lab = self._client.join_existing_lab(lid)
        jump_host = lab.get_node_by_label("jump-host")
        mgmtip = None
        retries = 0
        while mgmtip is None:
            if retries > 10:
                break

            for i in jump_host.interfaces():
                if i.discovered_ipv4 and len(i.discovered_ipv4) > 0:
                    mgmtip = i.discovered_ipv4[0]
                    break

            retries += 1
            time.sleep(1)

        return mgmtip

    def get_lab_consoles(self):
        if len(self._consoles) == 0:
            raise Exception("ERROR: Consoles have not been generated yet")

        return self._consoles

    @staticmethod
    def _extract_configuration_task(node, pylab):
        if node.is_booted() and node.label != "jump-host":
            # We do this to ensure the extract is at the enable prompt.
            try:
                pylab.run_command(node.label, "show version")
            except Exception:
                pass
            node.extract_configuration()

    def archive_lab(self, lid, filename, node_password):
        try:
            lab = self._client.join_existing_lab(lid)
        except LabNotFound:
            return
        # The client library prints "API Error" warnings when a node doesn't support extraction.  Quiet these.
        logger = logging.getLogger("virl2_client.models.authentication")
        level = logger.getEffectiveLevel()
        logger.setLevel(logging.CRITICAL)
        pylab = ClPyats(lab)
        os.environ["PYATS_USERNAME"] = node_password
        os.environ["PYATS_PASSWORD"] = node_password
        os.environ["PYATS_AUTH_PASS"] = node_password
        pylab.sync_testbed(self._username, self._password)
        with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
            future_nodes = {
                executor.submit(CML._extract_configuration_task, node, pylab):
                node
                for node in lab.nodes()
            }
            for fn in concurrent.futures.as_completed(future_nodes):
                try:
                    fn.result()
                except Exception:
                    pass

        logger.setLevel(level)
        with open(filename, "w") as fd:
            fd.write(lab.download())

    def remove_lab(self, lid):
        try:
            lab = self._client.join_existing_lab(lid)
        except LabNotFound:
            return
        lab.stop(wait=True)
        lab.wipe(wait=True)
        lab.remove()

    def get_student(self, student):
        session = self._client.session
        try:
            r = session.get(f"{self._client._base_url}users/{student}")
            r.raise_for_status()
        except Exception as e:
            if r.status_code == 404:
                return None

            raise Exception(f"ERROR: Failed to query for student: {e}")
        else:
            return r.json()

    def add_student(self, student, name, password):
        session = self._client.session
        try:
            payload = {"password": password, "fullname": name}
            r = session.post(f"{self._client._base_url}users/{student}",
                             json=payload)
            r.raise_for_status()
        except Exception as e:
            raise Exception(f"ERROR: Failed to add new student: {e}")

    def remove_student(self, student):
        session = self._client.session
        try:
            r = session.delete(f"{self._client._base_url}users/{student}")
            r.raise_for_status()
        except Exception as e:
            raise Exception(f"ERROR: Failed to remove student: {e}")
コード例 #9
0
if args.action == 'create':
    lab = import_lab(client_library, args.topology)

    f = open(".lab_id", "w")
    f.write(lab.id)
    f.close()

    print('Starting ' + lab.title + '...')
    lab.start(wait=True)

    print('Done!')

if args.action == 'destroy':
    f = open(".lab_id", "r")
    lab_id = f.read()
    f.close()

    print('Lab ID is ' + lab_id)
    lab = client_library.join_existing_lab(lab_id)

    print('Stoping lab' + lab_id)
    lab.stop()

    print('Wiping lab' + lab_id + ' out')
    lab.wipe()

    print('Removing lab' + lab_id)
    client_library.remove_lab(lab_id)

    print('Done!')
コード例 #10
0
ファイル: virl.py プロジェクト: iantriggs/ansible-virl
class virlModule(object):
    def __init__(self, module, function=None):
        self.module = module
        self.params = module.params
        self.result = dict(changed=False)
        self.headers = dict()
        self.function = function
        self.cookies = None
        self.json = None

        self.method = None
        self.path = None
        self.response = None
        self.status = None
        self.url = None
        self.params['force_basic_auth'] = True
        self.user = self.params['user']
        self.password = self.params['password']
        self.host = self.params['host']
        self.timeout = self.params['timeout']
        self.modifiable_methods = ['POST', 'PUT', 'DELETE']

        self.client = None

        self.login()

    def login(self):
        self.client = ClientLibrary('https://{0}'.format(self.host),
                                    self.user,
                                    self.password,
                                    ssl_verify=False)

    def get_lab_by_name(self, name):
        for lab in self.client.all_labs():
            if lab.name == name:
                return lab
        return None

    def get_node_by_name(self, lab, name):
        for node in lab.nodes():
            if node.label == name:
                return node
        return None

    def get_lab_by_id(self, lab_id):
        try:
            lab = self.client.join_existing_lab(lab_id, sync_lab=True)
        except Exception:
            lab = None

        return lab

    def exit_json(self, **kwargs):

        self.result.update(**kwargs)
        self.module.exit_json(**self.result)

    def fail_json(self, msg, **kwargs):

        self.result.update(**kwargs)
        self.module.fail_json(msg=msg, **self.result)
コード例 #11
0
                       cml_username,
                       cml_password,
                       ssl_verify=False,
                       raise_for_auth_failure=True,
                       allow_http=True)

#get lab
lab = client.find_labs_by_title("Jupyter Lab")[0]

#get lab testbed
pyats_testbed = lab.get_pyats_testbed()

#Add credentials to yaml file
doc = yaml.load(pyats_testbed)
doc["devices"]["terminal_server"]["connections"]["cli"][
    "username"] = cml_username
doc["devices"]["terminal_server"]["connections"]["cli"][
    "password"] = cml_password

# Write the YAML testbed out to a file
with open("lab_testbed.yaml", "w") as f:
    yaml.dump(doc, f)

#run command in a node
lab = client.join_existing_lab(lab.id)
print("Device -> " + str(lab.nodes()[0]))
node = lab.get_node_by_id(lab.nodes()[0].id)
lab.pyats.sync_testbed(cml_username, cml_password)
version = node.run_pyats_command("show config")
print(version)