def router_conf_file(network, router): """Returns filename for config file for router""" return "%s.conf" % ank.rtr_folder_name(network, router)
def router_dir(network, rtr): """Returns path for router rtr""" foldername = ank.rtr_folder_name(network, rtr) return os.path.join(netkit_dir(network, rtr), foldername)
def configure_netkit(self): """Generates Netkit and Zebra/Quagga specific configuration files.""" # Sets up netkit related files tap_host = ank.get_tap_host(self.network) ank_version = pkg_resources.get_distribution("AutoNetkit").version date = time.strftime("%Y-%m-%d %H:%M", time.localtime()) lab_template = lookup.get_template("netkit/lab.mako") startup_template = lookup.get_template("netkit/startup.mako") zebra_daemons_template = lookup.get_template( "quagga/zebra_daemons.mako") zebra_template = lookup.get_template("quagga/zebra.mako") sshd_template = lookup.get_template("linux/sshd.mako") motd_template = lookup.get_template("quagga/motd.mako") # Shared (common) configuration startup_daemon_list = [] #Setup ssh shutil.copy(resource_filename("AutoNetkit","lib/shadow"), shared_etc_dir()) startup_daemon_list.append("ssh") # Need to chown root dir for ssh keys # refer http://list.dia.uniroma3.it/pipermail/netkit.users/2010-February/000552.html use_ssh_key = False if config.settings['Netkit']['ssh key']: #chown root:root /root use_ssh_key = True f_startup = open( os.path.join(lab_dir(), "shared.startup"), 'wb') f_startup.write(startup_template.render( interfaces=[], add_localhost=True, #don't send out the tap interface del_default_route=True, daemons=startup_daemon_list, use_ssh_key = use_ssh_key, )) f_startup.close() # Files for indvidual node configuration #TODO: this needs to be created for each netkit host machine f_lab = open(os.path.join(lab_dir(), "lab.conf"), 'wb') lab_conf = {} tap_list_strings = {} ibgp_routers = ank.ibgp_routers(self.network) ebgp_routers = ank.ebgp_routers(self.network) igp_graph = ank.igp_graph(self.network) dns_servers = set(self.network.dns_servers()) routers = set(self.network.routers()) for node in self.network.devices(): #TODO: see if rtr label is still needed, if so replace with # appropriate naming module function rtr_folder_name = ank.rtr_folder_name(self.network, node) # sshd options f_sshd = open( os.path.join(sshd_dir(self.network, node), "sshd_config"), 'wb') f_sshd.write(sshd_template.render()) f_sshd.close() lab_conf[rtr_folder_name] = [] startup_daemon_list = ["zebra"] startup_int_list = [] # convert tap list from ips into strings # tap_int_id cannot conflict with already allocated interfaces # assume edges number sequentially, so next free int id is number of # edges node_tap_id = self.tap_interface_id(self.network, node) tap_list_strings[rtr_folder_name] = (node_tap_id, self.network[node].get('tap_ip')) if node in dns_servers: startup_daemon_list.append("bind") dns_memory = 64 # Allocate more memory to DNS server #TODO: remove key, val and make it just key: val lab_conf[rtr_folder_name].append( ('mem', dns_memory)) if config.settings['Netkit']['ssh key']: f_auth_keys = open(os.path.join(dot_ssh_dir(self.network, node), "authorized_keys"), "wb") f_auth_keys.write(config.settings['Netkit']['ssh key']) f_auth_keys.close() # Zebra Daemons zebra_daemon_list = [] f_zdaemons = open( os.path.join(zebra_dir(self.network, node), "daemons"), 'wb') # Always start Zebra zebra_daemon_list.append("zebra") if igp_graph.degree(node) > 0: zebra_daemon_list.append("ospfd") # Only start IGP process if IGP links if (node in ibgp_routers) or (node in ebgp_routers): zebra_daemon_list.append("bgpd") f_zdaemons.write(zebra_daemons_template.render( entryList = zebra_daemon_list, )) f_zdaemons.close() # MOTD f_zmotd = open( os.path.join(zebra_dir(self.network, node), "motd.txt"), 'wb') f_zmotd.write(motd_template.render( date = date, version = ank_version, password = self.zebra_password, )) # Main Zebra config f_z = open( os.path.join(zebra_dir(self.network, node), "zebra.conf"), 'wb') f_z.write( zebra_template.render( hostname = node.device_hostname, password = self.zebra_password, enable_password = self.zebra_password, use_snmp = True, use_debug = True, )) f_z.close() # Loopback interface lo_ip = self.network.lo_ip(node) startup_int_list.append({ 'int': 'lo:1', 'ip': str(lo_ip.ip), 'netmask': str(lo_ip.netmask), }) # Ethernet interfaces for link in self.network.links(node): int_id = self.interface_id(link.id) subnet = link.subnet # replace the / from subnet label collision_domain = "%s.%s" % (subnet.ip, subnet.prefixlen) # lab.conf has id in form host[0]=... for eth0 of host lab_conf[rtr_folder_name].append((link.id, collision_domain)) startup_int_list.append({ 'int': int_id, 'ip': str(link.ip), 'netmask': str(subnet.netmask), 'broadcast': str(subnet.broadcast), }) default_route = None if node.is_server: default_route = ank.default_route(node) # add default_route for server to router chown_bind = False if node in ank.dns_servers(self.network): chown_bind = True #Write startup file for this router f_startup = open( os.path.join(netkit_dir(self.network, node), "{0}.startup".format(rtr_folder_name)), 'wb') f_startup.write(startup_template.render( interfaces=startup_int_list, add_localhost=True, #don't send out the tap interface del_default_route=True, default_route = default_route, daemons=startup_daemon_list, chown_bind = chown_bind, )) f_startup.close() # Write lab file for whole lab f_lab.write(lab_template.render( conf = lab_conf, tapHost = tap_host, tapList = tap_list_strings, lab_description = "AutoNetkit generated lab", lab_version = date, #TODO: get this from config file lab_email = "*****@*****.**", lab_author = "AutoNetkit %s" % ank_version, #TODO: get this from config file lab_web = "www.autonetkit.org", ))
def collect_data(self, commands): shell = self.server.get_shell() shell.setecho(False) collected_data_dir = config.collected_data_dir netkit_data_dir = os.path.join(collected_data_dir, "netkit") if not os.path.isdir(netkit_data_dir): os.mkdir(netkit_data_dir) host_data_dir = os.path.join(netkit_data_dir, self.host_alias) if not os.path.isdir(host_data_dir): os.mkdir(host_data_dir) collect_timestamp_dir = os.path.join(host_data_dir, time.strftime("%Y%m%d_%H%M%S", time.localtime())) if not os.path.isdir(collect_timestamp_dir): os.mkdir(collect_timestamp_dir) servers = set(self.network.servers()) #TODO: need to have way to allow privexec.... or just disable enable password? #TODO: Put term len 0 into configs for node in self.network.devices(): routername = ank.fqdn(self.network, node) full_routername = ank.rtr_folder_name(self.network, node) user_exec_prompt = "%s>" % node.dns_hostname priv_exec_prompt = "%s#" % node.dns_hostname for port_command in commands: LOG.info("%s: running %s" % (routername, port_command)) telnet_port, command = port_command.split(":") if telnet_port == 'ssh': self.server.connect_vm(node.tap_ip, shell) shell.sendline(command) shell.expect(self.server.NETKIT_PROMPT) command_output = shell.before self.server.disconnect_vm(shell) shell.prompt() # need to ssh into this machine else: if node in servers: # don't try telnet into as zebra not running continue # use telnet shell.sendline("telnet %s %s" % (node.tap_ip, telnet_port)) shell.expect("Password:"******"1234") shell.expect(user_exec_prompt) shell.sendline("en") i = shell.expect(["Password:"******"1234") else: # all good, in priv exec pass # just to be sure set_term_length = "term len 0" shell.sendline(set_term_length) shell.expect(priv_exec_prompt) shell.sendline(command) shell.expect(priv_exec_prompt) # Can be an issue with the telnet x zebra command (not for bgpd it seems) command_output = shell.before # If no command output, captured the previous command, try again if command_output.strip() == set_term_length: shell.expect(priv_exec_prompt) command_output = shell.before shell.sendline("exit") shell.prompt() # from http://stackoverflow.com/q/295135/ command_filename_format = (re.sub('[^\w\s-]', '', command).strip().lower()) filename = "%s_%s_%s.txt" % (full_routername, command_filename_format, time.strftime("%Y%m%d_%H%M%S", time.localtime())) filename = os.path.join(collect_timestamp_dir, filename) with open( filename, 'w') as f_out: f_out.write(command_output)
def folder_name(self): return ank.rtr_folder_name(self.network, self)
def device_hostname(self): """ Replaces . with _ to make safe for router configs""" return ank.rtr_folder_name(self.network, self)