def telnet(node): """ telnet to a node """ if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif len(node) == 1: # assume default env env = 'default' running = helpers.check_sim_running(env) node = node[0] else: exit(call(['virl', 'telnet', '--help'])) if running: sim_name = running server = VIRLServer() details = server.get_sim_roster(sim_name) if node: try: node_dict = get_node_from_roster(node, details) node_name = node_dict.get("NodeName") ip = node_dict['managementIP'] proxy = node_dict.get("managementProxy") # use user specified telnet command if 'VIRL_TELNET_COMMAND' in server.config: cmd = server.config['VIRL_TELNET_COMMAND'] cmd = cmd.format(host=ip) print("Calling user specified command: {}".format(cmd)) exit(call(cmd.split())) if proxy == 'lxc': lxc = get_mgmt_lxc_ip(details) click.secho("Attemping telnet connection" " to {} at {} via ssh {}".format( node_name, ip, lxc)) cmd = 'ssh -t {}@{} "telnet {}"' cmd = cmd.format(server.user, lxc, ip) exit(call(cmd, shell=True)) else: # handle the "flat" networking case click.secho("Attemping telnet connection" " to {} at {}".format(node_name, ip)) exit(call(['telnet', ip])) except AttributeError: click.secho("Could not find management info " "for {}:{}".format(env, node), fg="red") except KeyError: click.secho("Unknown node {}:{}".format(env, node), fg="red") else: return details.json()
def start(node): """ start a node """ if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif len(node) == 1: # assume default env env = 'default' running = helpers.check_sim_running(env) node = node[0] else: exit(call(['virl', 'start', '--help'])) if running: sim_name = running server = VIRLServer() resp = server.start_node(sim_name, node) if resp.ok: click.secho("Started node {}".format(node)) else: click.secho("Error starting Node {}: {}".format(node, resp), fg="red")
def stop1(node): """ stop a node """ if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif len(node) == 1: # assume default env env = "default" running = helpers.check_sim_running(env) node = node[0] else: exit(call([get_command(), "stop", "--help"])) if running: sim_name = running server = VIRLServer() resp = server.stop_node(sim_name, node) if resp.ok: click.secho("Stopped node {}".format(node)) else: click.secho("Error Stopping Node {}: {}".format(node, resp), fg="red")
def ssh(node): """ ssh to a node """ if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif len(node) == 1: # assume default env env = 'default' running = helpers.check_sim_running(env) node = node[0] else: exit(call(['virl', 'ssh', '--help'])) if running: sim_name = running server = VIRLServer() details = server.get_sim_roster(sim_name) if node: try: node_dict = get_node_from_roster(node, details) node_name = node_dict.get("NodeName") ip = node_dict['managementIP'] proxy = node_dict.get("managementProxy") if proxy == 'lxc': lxc = get_mgmt_lxc_ip(details) if lxc: click.secho("Attemping ssh connection" "to {} at {} via {}".format(node_name, ip, lxc)) cmd = 'ssh -o "ProxyCommand ssh -W %h:%p {}@{}" {}@{}' cmd = cmd.format(server.user, lxc, 'cisco', ip) exit(call(cmd, shell=True)) else: # handle the "flat" networking case click.secho("Attemping ssh connection" "to {} at {}".format(node_name, ip)) exit(call(['ssh', 'cisco@{}'.format(ip)])) except AttributeError: click.secho("Could not find management info" "for {}:{}".format(env, node), fg="red") except KeyError: click.secho("Unknown node {}:{}".format(env, node), fg="red") else: return details.json()
def ansible(env, **kwargs): """ generate ansible inventory """ if kwargs.get("output"): # user specified output filename file_name = kwargs.get("output") else: # writes to <env>_testbed.yaml by default file_name = '{}_inventory.yaml'.format(env) running = helpers.check_sim_running(env) if running: sim_name = running server = VIRLServer() roster = server.get_sim_roster(sim_name) # sim_name = "topology-fpyHFs" virl_data = server.export(sim_name, ip=True).content interfaces = server.get_interfaces(sim_name).json() inventory_yaml = ansible_inventory_generator(sim_name, virl_data, roster=roster, interfaces=interfaces) click.secho("Writing {}".format(file_name)) with open(file_name, 'w') as yaml_file: yaml_file.write(inventory_yaml) else: click.secho("couldnt generate testbed for for env: {}".format(env), fg='red')
def pyats1(env, **kwargs): """ Generates a pyats testbed config for an environment """ if kwargs.get("output"): # user specified output filename file_name = kwargs.get("output") else: # writes to <env>_testbed.yaml by default file_name = "{}_testbed.yaml".format(env) running = helpers.check_sim_running(env) if running: sim_name = running server = VIRLServer() roster = server.get_sim_roster(sim_name) # sim_name = "topology-fpyHFs" virl_data = server.export(sim_name, ip=True).content interfaces = server.get_interfaces(sim_name).json() testbed_yaml = pyats_testbed_generator1(sim_name, virl_data, roster=roster, interfaces=interfaces) click.secho("Writing {}".format(file_name)) with open(file_name, "w") as yaml_file: yaml_file.write(testbed_yaml) else: click.secho("couldnt generate testbed for for env: {}".format(env), fg="red")
def console(node, display, **kwargs): """ console for node """ server = VIRLServer() if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif display: # only displaying output env = 'default' running = helpers.check_sim_running(env) node = None elif len(node) == 1: # assume default env env = 'default' running = helpers.check_sim_running(env) node = node[0] else: # node was not specified, display usage exit(call(['virl', 'console', '--help'])) if running: sim_name = running resp = server.get_node_console(sim_name, node=node) if node: click.secho("Attempting to connect to console " "of {}".format(node)) try: ip, port = resp.json()[node].split(':') exit(call(['telnet', ip, port])) except AttributeError: click.secho("Could not find console info for " "{}:{}".format(env, node), fg="red") except KeyError: click.secho("Unknown node {}:{}".format(env, node), fg="red") else: # defaults to displaying table console_table(resp.json())
def nodes(env, **kwargs): """ get nodes for sim_name """ running = helpers.check_sim_running(env) if running: sim_name = running server = VIRLServer() details = server.get_sim_roster(sim_name) node_list_table(details) else: click.secho("Environment {} is not running".format(env), fg='red')
def logs1(env, **kwargs): """ Retrieves log information for the provided simulation """ running = helpers.check_sim_running(env) if running: sim_name = running server = VIRLServer() resp = server.get_logs(sim_name) log_table(resp.json()['events']) else: click.secho("could not find logs for for env: {}".format(env), fg='red')
def uwm1(env): """ opens UWM for the sim """ server = VIRLServer() running = helpers.check_sim_running(env) if running: sim_name = running # luanches uwm url = "http://{}:{}@{}/simulation/{}/{}" url = url.format(server.user, server.passwd, server.host, server.user, sim_name) subprocess.Popen(['open', url])
def viz(env): """ opens live visualization for the sim """ server = VIRLServer() running = helpers.check_sim_running(env) if running: sim_name = running url = "http://{}:19402/?sim_id={}#/layer/phy".format(server.host, sim_name) subprocess.Popen(['open', url]) else: click.secho('No Running simulation to visualize', fg="red")
def telnet(node): """ telnet to a node """ if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] else: # assume default env env = 'default' running = helpers.check_sim_running(env) node = node[0] if running: sim_name = running server = VIRLServer() details = server.get_sim_roster(sim_name) #resp = server.get_node_console(sim_name, node=node) for node_dict in details.values(): node_name = node_dict.get("NodeName") if node_name == node: click.secho( "Attemping telnet connection to {}".format(node_name))
def nso1(env, syncfrom, **kwargs): """ generate nso inventory """ if kwargs.get("output"): # user specified output filename file_name = kwargs.get("output") else: # writes to <env>.json by default file_name = None running = helpers.check_sim_running(env) if running: sim_name = running server = VIRLServer() roster = server.get_sim_roster(sim_name) # sim_name = "topology-fpyHFs" virl_data = server.export(sim_name, ip=True).content interfaces = server.get_interfaces(sim_name).json() payload = nso_payload_generator1(sim_name, virl_data, roster=roster, interfaces=interfaces) if file_name: # pragma: no cover click.secho("Writing payload to {}".format(file_name)) with open(file_name, "w") as payload_file: payload_file.write(payload) else: click.secho("Updating NSO....") nso_obj = NSO() nso_response = nso_obj.update_devices(payload) if nso_response.ok: click.secho("Successfully added VIRL 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("couldnt generate testbed for for env: {}".format(env), fg="red")
def up(env, **kwargs): """ start a virl simulation """ if kwargs['f']: fname = kwargs['f'] else: fname = 'topology.virl' if os.path.exists(fname): running = check_sim_running(env) if not running: click.secho('Creating {} environment from {}'.format(env, fname)) with open(fname) as fh: data = fh.read() server = VIRLServer() dirpath = os.getcwd() foldername = os.path.basename(dirpath) sim_name = "{}_{}_{}".format(foldername, env, generate_sim_id()) resp = server.launch_simulation(sim_name, data) store_sim_info(resp.text, env=env) # 'topology-2lkx2' else: click.secho('Sim {} already running'.format(running)) else: click.secho('Could not find topology.virl. Maybe try -f', fg="red")
def down(sim_name=None, env='default', **kwargs): """ stop a virl simulation """ # by env name running = check_sim_running(env) if running: sim_name = running # by sim name elif sim_name: sim_name = sim_name else: click.secho("Could not find sim for environment {}".format(env)) exit(1) server = VIRLServer() resp = server.stop_simulation(sim_name) remove_sim_info(env=env) if not resp.ok: cause = resp.json()['cause'] result = click.style(cause, fg="red") else: result = click.style(resp.text, fg="green") click.secho("Shutting Down Simulation {}.....".format(sim_name)), click.echo(result)
def ssh1(node): """ ssh to a node """ if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif len(node) == 1: # assume default env env = "default" running = helpers.check_sim_running(env) node = node[0] else: exit(call(["virl", "ssh", "--help"])) if running: sim_name = running server = VIRLServer() details = server.get_sim_roster(sim_name) # default ssh username can be overriden username = server.config.get("VIRL_SSH_USERNAME", "cisco") if node: try: node_dict = get_node_from_roster(node, details) node_name = node_dict.get("NodeName") ip = node_dict["managementIP"] proxy = node_dict.get("managementProxy") if "VIRL_SSH_COMMAND" in server.config: cmd = server.config["VIRL_SSH_COMMAND"] cmd = cmd.format(host=ip, username=username) print("Calling user specified command: {}".format(cmd)) exit(call(cmd.split())) if proxy == "lxc": lxc = get_mgmt_lxc_ip(details) if lxc: click.secho("Attemping ssh connection" "to {} at {} via {}".format( node_name, ip, lxc)) cmd = 'ssh -o "ProxyCommand ssh -W %h:%p {}@{}" {}@{}' cmd = cmd.format(server.user, lxc, username, ip) exit(call(cmd, shell=True)) else: # handle the "flat" networking case click.secho("Attemping ssh connection" "to {} at {}".format(node_name, ip)) exit(call(["ssh", "{}@{}".format(username, ip)])) except AttributeError: click.secho("Could not find management info" " for {}:{}".format(env, node), fg="red") except KeyError: click.secho("Unknown node {}:{}".format(env, node), fg="red") else: return details.json()
def up1(repo=None, provision=False, **kwargs): """ start a virl simulation """ fname = kwargs["f"] env = kwargs["e"] wait_time = kwargs["wait_time"] if os.path.exists(fname): running = check_sim_running(env) if not running: click.secho("Creating {} environment from {}".format(env, fname)) with open(fname) as fh: data = fh.read() server = VIRLServer() # we can expose fairly aribtary substitutions here... # anything that may differ usually related to networking.... # <dirty hack> subs = { "{{ gateway }}": server.get_gateway_for_network("flat"), "{{ flat1_gateway }}": server.get_gateway_for_network("flat1"), "{{ dns_server }}": server.get_dns_server_for_network("flat"), } # also can change some VIRL/ANK defaults subs["rsa modulus 768"] = "rsa modulus 1024" for tag, value in subs.items(): if tag in data: if value: # split off the braces humanize = tag click.secho("Localizing {} with: {}".format( humanize, value)) data = data.replace(tag, value) # </dirty hack> dirpath = os.getcwd() foldername = os.path.basename(dirpath) sim_name = "{}_{}_{}".format(foldername, env, generate_sim_id()) resp = server.launch_simulation(sim_name, data) store_sim_info(resp.text, env=env) # 'topology-2lkx2' if provision: nodes = server.get_node_list(sim_name) msg = "Waiting {} minutes for nodes to come online...." msg = msg.format(wait_time) click.secho(msg) maxtime = time.time() + 60 * int(wait_time) with click.progressbar(nodes) as all_nodes: for node in all_nodes: if time.time() > maxtime: click.secho("") click.secho("Max time expired", fg="red") click.secho("All nodes may not be online", fg="red") break node_online = False while not node_online: if time.time() > maxtime: break time.sleep(20) node_online = server.check_node_reachable( sim_name, node) else: click.secho("Sim {} already running".format(running)) else: # try to pull from virlfiles if repo: call([get_command(), "pull", repo]) call([get_command(), "up"]) else: click.secho("Could not find topology.virl. Maybe try -f", fg="red")
def console1(node, display, **kwargs): """ console for node """ server = VIRLServer() if len(node) == 2: # we received env and node name env = node[0] running = helpers.check_sim_running(env) node = node[1] elif display: # only displaying output env = "default" running = helpers.check_sim_running(env) node = None elif len(node) == 1: # assume default env env = "default" running = helpers.check_sim_running(env) node = node[0] else: # node was not specified, display usage exit(call([get_command(), "console", "--help"])) if running: sim_name = running resp = server.get_node_console(sim_name, node=node) if node: click.secho("Attempting to connect to console " "of {}".format(node)) try: ip, port = resp.json()[node].split(":") # use user specified telnet command if "VIRL_CONSOLE_COMMAND" in server.config: cmd = server.config["VIRL_CONSOLE_COMMAND"] cmd = cmd.format(host=ip, port=port) 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(): exit(call(["telnet", ip, port])) # why is shit so complicated? else: exit(call(["telnet", ip, port])) except AttributeError: click.secho("Could not find console info for " "{}:{}".format(env, node), fg="red") except KeyError: click.secho("Unknown node {}:{}".format(env, node), fg="red") else: # defaults to displaying table console_table1(resp.json())