Пример #1
0
def extract(host, tar_file, cd_dir):
    from Exscript import Account
    from Exscript.util.start import start
    from Exscript.util.match import first_match
    from Exscript.protocols.Exception import InvalidCommandException

    def starting_host(protocol, index, data):
        print data.group(index)

    def lab_started(protocol, index, data):
        print "Lab started"

    def do_something(thread, host, conn):
        conn.add_monitor(r'Starting (\S+)', starting_host)
        conn.add_monitor(r'The lab has been started', lab_started)
        #conn.data_received_event.connect(data_received)
        conn.execute('tar -xzf %s' % tar_file)
        conn.execute('cd %s' % cd_dir)
        conn.execute('vlist')
        conn.execute("lclean")
        print "Starting lab"
        start_command = 'lstart -p5 -o --con0=none'
        try:
            conn.execute(start_command)
        except InvalidCommandException, error:
            if "already running" in str(error):
                print "Already Running" #TODO: handle appropriately
                print "Halting previous lab"
                conn.execute("vclean -K")
                print "Halted previous lab"
                print "Starting lab"
                conn.execute(start_command)
        first_match(conn, r'^The lab has been started')
        print "HERE"
        conn.send("exit")
Пример #2
0
def extract(host, tar_file, cd_dir):
    from Exscript import Account
    from Exscript.util.start import start
    from Exscript.util.match import first_match
    from Exscript.protocols.Exception import InvalidCommandException

    def starting_host(protocol, index, data):
        print data.group(index)

    def lab_started(protocol, index, data):
        print "Lab started"

    def do_something(thread, host, conn):
        conn.add_monitor(r"Starting (\S+)", starting_host)
        conn.add_monitor(r"The lab has been started", lab_started)
        # conn.data_received_event.connect(data_received)
        conn.execute("tar -xzf %s" % tar_file)
        conn.execute("cd %s" % cd_dir)
        conn.execute("vlist")
        conn.execute("lclean")
        print "Starting lab"
        start_command = "lstart -p5 -o --con0=none"
        try:
            conn.execute(start_command)
        except InvalidCommandException, error:
            if "already running" in str(error):
                print "Already Running"  # TODO: handle appropriately
                print "Halting previous lab"
                conn.execute("vclean -K")
                print "Halted previous lab"
                print "Starting lab"
                conn.execute(start_command)
        first_match(conn, r"^The lab has been started")
        print "HERE"
        conn.send("exit")
Пример #3
0
  def config(self,resp):
    ret = ""
    if not isinstance(resp, str): 
      print "No Config found"
      return ""
    remove = [
      "^\!",				#Remove comments
      "^Time: ",			#Remove timestamp from nxos
      "^show running-config",
      "^Building configuration",
      "Current configuration \: \d+ bytes",
    ]
    
    #Find hostname and put it on top.
    
    
    
    for line in resp.splitlines():
      #Remove lines matcing "remove" variable
      r = False
      for _remove in remove:
        if re.search(_remove,line): r = True
      if r: continue
      
      #Remove Timestamp from NX-OS
#      if re.search("^Time: ",line): continue


      #Removing passwords from configuration
      a = first_match(line, "^((enable )?(password|passwd)( level \d+)?)", re.I)
      if a[0] and self._config["filter_pw"] >= 1:
        ret += "!%s <removed>\n" % a[0]
        continue  
      a = first_match(line, "^(username (\S+)(\s.*)? secret)", re.I)
      if a[0] and self._config["filter_pw"] >= 1:
        ret += "!%s <removed>\n" % a[0]
        continue
      a = first_match(line, "^(enable secret) ", re.I)
      if a and self._config["filter_pw"] >= 1:
        ret += "!%s <removed>\n" % a
        continue
      a = first_match(line, "^(username (\S+)(\s.*)? (privilege \d+ )?(password|secret) )((\d) \S+|\S+)", re.I)
      if a[0] and self._config["filter_pw"] >= 1:
        ret += "!%s <removed>\n" % a[0]
        continue
      
      a = first_match(line, "^hostname", re.I)
      if a:
        ret += "%s\n" % a
        continue

      
        
      ret += "%s\n" % line
    return ret
Пример #4
0
def extract(host, username, tar_file, cd_dir, timeout = 3600, key_filename = None, password = None, verbosity = 0):
    """Extract and start lab"""
    log.debug("Extracting and starting lab on %s" % (host))
    log.info("Extracting and starting Netkit lab")
    from Exscript import Account
    from Exscript.util.start import start
    from Exscript.util.match import first_match
    from Exscript import PrivateKey
    from Exscript.protocols.Exception import InvalidCommandException, LoginFailure

    messaging = ank_messaging.AnkMessaging()

    def starting_host(protocol, index, data):
        m = re.search('\\"(\S+)\\"', data.group(index))
        if m:
            hostname = m.group(1)
            log.info(data.group(index)) #TODO: use regex to strip out just the machine name
            body = {"starting": hostname}
            messaging.publish_json(body)

    def lab_started(protocol, index, data):
        log.info("Lab started on %s" % host)
        body = {"lab started": host}
        messaging.publish_json(body)

    def make_not_found(protocol, index, data):
        log.warning("Make not installed on remote host %s. Please install make and retry." % host)
        return

    def start_lab(thread, host, conn):
        conn.set_timeout(timeout)
        conn.add_monitor(r'Starting (\S+)', starting_host)
        conn.add_monitor(r'The lab has been started', lab_started)
        conn.add_monitor(r'make: not found', make_not_found)
        #conn.data_received_event.connect(data_received)
        conn.execute('cd %s' % cd_dir)
        conn.execute('lhalt -q')
        conn.execute('lcrash -k')
        conn.execute("lclean")
        conn.execute('cd') # back to home directory tar file copied to
        conn.execute('rm -Rf rendered')
        conn.execute('tar -xzf %s' % tar_file)
        conn.execute('cd %s' % cd_dir)
        conn.execute('vlist')
        conn.execute("lclean")
        log.info("Starting lab")
        start_command = 'lstart -p20 -o--con0=none'
        try:
            conn.execute(start_command)
        except InvalidCommandException, error:
            if "already running" in str(error):
                time.sleep(1)
                conn.execute(start_command)
        first_match(conn, r'^The lab has been started')
        conn.send("exit")
Пример #5
0
def port_FREE(switch, username, password, verbose, snakerange):
    error = []
    snakearray = port_extractor(snakerange)
    conn = login(switch, username, password, verbose)
    #first check if we may disable all the ports in the snake-array, is there a 'SNAKEPORT' in its port-name?
    for port in snakearray:
        conn.execute('show interfaces ' + port + ' | include Port name')
        maydisable = first_match(conn, r'(SNAKETEST:)')
        if maydisable != 'SNAKETEST:':
            error.append(
                'interface ' + port +
                ' has no port-name with "SNAKETEST", I won\'t continue')
    raise_error(error, conn)

    #we can go ahead and disable the ports
    conn.execute('configure terminal')
    for port in snakearray:
        conn.execute('interface ' + port)
        conn.execute('disable')
        conn.execute('port-name FREE')
        #conn.execute('clear statistics '+ port)

#remove the VLANs
    remove_vlans(snakearray, conn)
    quit(conn)
Пример #6
0
def get_port_dbm_and_type(port, error, conn):
    port_type_tx_rx = [port, 'unknown', 'None', 'None']
    conn.execute('show media ' + port + ' | include Type')
    port_type_tx_rx[1] = first_match(
        conn, r'(10GE LR|10GE ER|100GE 10x10|100GE LR4)')
    if port_type_tx_rx[1] == 'unknown':
        error.append(
            port +
            ' has an unknown port-type, please update the script to include it'
        )

    port_modport = re.split(' ', port)
    port_module = re.split('/', port_modport[1])
    conn.execute('show  optic ' + port_module[0] + ' | include ' +
                 port_modport[1] + '[\ t]')

    port_tx_rx = any_match(
        conn, r'([-]?[0-9]*\.[0-9]*[ \t]dBm[ \t]+[-]?[0-9]*\.[0-9]*[ \t]dBm)')
    port_tx_rx = re.split('\s+', str(port_tx_rx))
    port_tx = port_tx_rx[0]
    port_tx = re.split("'", port_tx)
    port_type_tx_rx[2] = port_tx[1]
    port_type_tx_rx[3] = port_tx_rx[2]

    return port_type_tx_rx
Пример #7
0
def port_status_check (port, conn):
	conn.execute('show interfaces brief '+ port)
	Link = first_match(conn, r'(Disab)')
	if Link == 'Disab':
		return 1
	Link = first_match(conn, r'(Empty)')
	if Link == 'Empty':
		return 2
	Link = first_match(conn, r'(Down)')
	if Link == 'Down':
		return 3
	Link = first_match(conn, r'(Up)')
	if Link == 'Up':
		Port_State = first_match(conn, r'(Forward)')
		if Port_State == 'Forward':
			return 4
		#There should be other possibilities than Port_State=Forward right?
	return 0
Пример #8
0
def port_status_check(port, conn):
    conn.execute('show interfaces brief ' + port)
    Link = first_match(conn, r'(Disab)')
    if Link == 'Disab':
        return 1
    Link = first_match(conn, r'(Empty)')
    if Link == 'Empty':
        return 2
    Link = first_match(conn, r'(Down)')
    if Link == 'Down':
        return 3
    Link = first_match(conn, r'(Up)')
    if Link == 'Up':
        Port_State = first_match(conn, r'(Forward)')
        if Port_State == 'Forward':
            return 4
        #There should be other possibilities than Port_State=Forward right?
    return 0
Пример #9
0
    def testFirstMatch(self):
        from Exscript.util.match import first_match

        string = 'my test'
        self.assertIsNone(first_match(string, r'aaa'))
        self.assertEqual(first_match(string, r'\S+'), 'my test')
        self.assertIsNone(first_match(string, r'(aaa)'))
        self.assertEqual(first_match(string, r'(\S+)'), 'my')
        self.assertEqual(first_match(string, r'(aaa) (\S+)'), (None, None))
        self.assertEqual(first_match(string, r'(\S+) (\S+)'), ('my', 'test'))
        self.assertEqual(
            first_match("24.1632", r'(\d+)\.(\d+)'), ('24', '1632'))
        self.assertEqual(first_match("24", r'(\d+)\.?(\d+)?'), ('24', None))

        multi_line = 'hello\nworld\nhello world'
        self.assertEqual(first_match(multi_line, r'(he)llo'), 'he')
Пример #10
0
def remove_vlans(snakearray, conn):
	for port in snakearray:
		conn.execute('show vlan ' + port)
		vlan = first_match(conn, r'(VLAN: [0-9]+)')
		vlan = re.split(' ', vlan)
		conn.execute('no vlan ' + vlan[1])
		error1 = any_match(conn, r'(Error: Cannot undo the configuration as)')
		error2 = any_match(conn, r'(session is using this mode\.)')
		if (error1!=[])and(error2!=[]):
			quit(conn)
			raise Exception('Another user is already using this mode, remove him/her/it so we can move on')
Пример #11
0
def untagged (port, currentvlan, error, conn):
	currentvlan = str(currentvlan)
	conn.execute('untagged ' + port)
	error1 = any_match(conn, r'(Error: ports)')
	error2 = any_match(conn, r'(are untagged in some user vlans)')
	if (error1!=[])and(error2!=[]):
		#Check if the VLAN error was becouse the port is already in currentvlan, if so then leave it there
		conn.execute('show vlan ' + port)
		vlan = first_match(conn, r'(VLAN: [0-9]+)')
		vlan = first_match(vlan, r'([0-9]+)') 
		if (vlan != currentvlan):
			#Check if the port is already in another snake VLAN 'SNAKE-VLAN', if so then we may replace it
			conn.execute('show vlan brief | include ' + vlan +'[\ t]')
			vlan_name = first_match(conn, r'(SNAKE-TEST)')
			if vlan_name == 'SNAKE-TEST':
				conn.execute('vlan '+ vlan)
				conn.execute('no untagged ' + port)
				conn.execute('vlan ' + currentvlan)
				conn.execute('untagged ' + port)
			else: 
				error.append(port + ' is already untagged in ' + vlan)
Пример #12
0
def untagged(port, currentvlan, error, conn):
    currentvlan = str(currentvlan)
    conn.execute('untagged ' + port)
    error1 = any_match(conn, r'(Error: ports)')
    error2 = any_match(conn, r'(are untagged in some user vlans)')
    if (error1 != []) and (error2 != []):
        #Check if the VLAN error was becouse the port is already in currentvlan, if so then leave it there
        conn.execute('show vlan ' + port)
        vlan = first_match(conn, r'(VLAN: [0-9]+)')
        vlan = first_match(vlan, r'([0-9]+)')
        if (vlan != currentvlan):
            #Check if the port is already in another snake VLAN 'SNAKE-VLAN', if so then we may replace it
            conn.execute('show vlan brief | include ' + vlan + '[\ t]')
            vlan_name = first_match(conn, r'(SNAKE-TEST)')
            if vlan_name == 'SNAKE-TEST':
                conn.execute('vlan ' + vlan)
                conn.execute('no untagged ' + port)
                conn.execute('vlan ' + currentvlan)
                conn.execute('untagged ' + port)
            else:
                error.append(port + ' is already untagged in ' + vlan)
Пример #13
0
  def version(self, resp):
    ret = ""
    # Get system image name
    if not isinstance(resp, str): 
      print "No version found"
      return ""
    for line in resp.splitlines():
      #print "!%s" % line
      a = first_match(line, r'System image file is "([^\"]*)"', re.I)
      if a: ret +=  "!IMAGE: %s\n" % a; continue

      a = first_match(line, r'^(Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$', re.I)
      if a[1]: ret += "!IMAGE: Software %s, %s\n" % (a[1], a[2]); continue

      a = first_match(line, r'^ROM:.*', re.I)
      if a: ret += "!ROM: %s\n" % a; continue

      a = first_match(line, r'BOOTLDR:.*', re.I)
      if a: ret += "!BOOTLDR: %s\n" % a; continue
      
      a = first_match(line, r'(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes', re.I)
      if a[0]: ret += "!TYPE: %s (%s)\n!MEMORY: %s\n" % (a[0], a[1], a[2]) ; continue

      a = first_match(line, r'^Configuration register is (.*)$')
      if a: ret += "!CONFREG: %s\n" % a; continue
    
    return ret
Пример #14
0
def remove_vlans(snakearray, conn):
    for port in snakearray:
        conn.execute('show vlan ' + port)
        vlan = first_match(conn, r'(VLAN: [0-9]+)')
        vlan = re.split(' ', vlan)
        conn.execute('no vlan ' + vlan[1])
        error1 = any_match(conn, r'(Error: Cannot undo the configuration as)')
        error2 = any_match(conn, r'(session is using this mode\.)')
        if (error1 != []) and (error2 != []):
            quit(conn)
            raise Exception(
                'Another user is already using this mode, remove him/her/it so we can move on'
            )
Пример #15
0
    def testFirstMatch(self):
        from Exscript.util.match import first_match

        string = 'my test'
        self.assert_(first_match(string, r'aaa') is None)
        self.assert_(first_match(string, r'\S+') == 'my test')
        self.assert_(first_match(string, r'(aaa)') is None)
        self.assert_(first_match(string, r'(\S+)') == 'my')
        self.assert_(first_match(string, r'(aaa) (\S+)') == (None, None))
        self.assert_(first_match(string, r'(\S+) (\S+)') == ('my', 'test'))

        multi_line = 'hello\nworld\nhello world'
        self.assert_(first_match(multi_line, r'(he)llo') == 'he')
Пример #16
0
    def testFirstMatch(self):
        from Exscript.util.match import first_match

        string = 'my test'
        self.assertTrue(first_match(string, r'aaa') is None)
        self.assertTrue(first_match(string, r'\S+') == 'my test')
        self.assertTrue(first_match(string, r'(aaa)') is None)
        self.assertTrue(first_match(string, r'(\S+)') == 'my')
        self.assertTrue(first_match(string, r'(aaa) (\S+)') == (None, None))
        self.assertTrue(first_match(string, r'(\S+) (\S+)') == ('my', 'test'))

        multi_line = 'hello\nworld\nhello world'
        self.assertTrue(first_match(multi_line, r'(he)llo') == 'he')
def dump_config(job, host, conn):
    """Connect to device, trim config file a bit, write to file"""
    conn.execute('term len 0')
    conn.execute('show run')
    #get the actual hostname of the device
    hostname = eum.first_match(conn, r'^hostname\s(.+)$')
    cfg_file = 'c:\\network_configs\\' + hostname.strip() + '.cfg'
    config = conn.response.splitlines()
    # a little cleanup
    for i in range(3):
        config.pop(i)
    config.pop(-0)
    config.pop(-1)
    # write config to file
    with open(cfg_file, 'w') as f:
        for line in config:
            f.write(line +'\n')
Пример #18
0
def get_port_dbm_and_type(port, error, conn):
	port_type_tx_rx = [port, 'unknown', 'None', 'None']
	conn.execute('show media '+ port +' | include Type')
	port_type_tx_rx[1] = first_match(conn, r'(10GE LR|10GE ER|100GE 10x10|100GE LR4)')
	if port_type_tx_rx[1] == 'unknown':   
		error.append(port + ' has an unknown port-type, please update the script to include it')

	port_modport = re.split(' ', port)
	port_module = re.split('/', port_modport[1])
	conn.execute('show  optic '+ port_module[0] +' | include ' + port_modport[1] + '[\ t]')	

	port_tx_rx = any_match(conn, r'([-]?[0-9]*\.[0-9]*[ \t]dBm[ \t]+[-]?[0-9]*\.[0-9]*[ \t]dBm)')
	port_tx_rx = re.split('\s+', str(port_tx_rx))
	port_tx = port_tx_rx[0]
	port_tx = re.split("'", port_tx)
	port_type_tx_rx[2] = port_tx[1]
	port_type_tx_rx[3] = port_tx_rx[2]
	
	return port_type_tx_rx
Пример #19
0
  def backup(self, conn, device):

    device.make = 'Cisco'

    self.init(conn)

    # collect data
    running_config = self.get_running_config(conn)
    device.save_config('running-config', running_config)

    startup_config = self.get_startup_config(conn)
    device.save_config('startup-config', startup_config)


    device.hostname = first_match("".join(running_config).replace('\r','\r\n'), r'^hostname (\S+)')

    device.model, device.serial_number, \
    device.type, device.software_version = self.parse_version(conn)

    device.save()
Пример #20
0
def port_FREE(switch, username, password, verbose, snakerange):
	error = []
	snakearray = port_extractor(snakerange)
	conn = login(switch, username, password, verbose)
#first check if we may disable all the ports in the snake-array, is there a 'SNAKEPORT' in its port-name?
	for port in snakearray:
		conn.execute('show interfaces '+ port + ' | include Port name')   
		maydisable = first_match(conn, r'(SNAKETEST:)')
		if maydisable != 'SNAKETEST:':
			error.append('interface ' + port + ' has no port-name with "SNAKETEST", I won\'t continue')
	raise_error(error, conn)

#we can go ahead and disable the ports
	conn.execute('configure terminal')
	for port in snakearray:
		conn.execute('interface ' + port)
		conn.execute('disable')
		conn.execute('port-name FREE')
		#conn.execute('clear statistics '+ port)

#remove the VLANs
	remove_vlans(snakearray, conn)
	quit(conn)
Пример #21
0
  def parse_version(self, conn):

    conn.execute('show version')

    version = first_match(conn, r'^(?:Cisco )?IOS.+Version (\S[^\s,]+)')
    if not version:
      version = first_match(conn, r'^Version\s+V(\d+\.\d+\.\d+')

    type = "Router"
    if first_match(conn, r'\b(cat|(WS|ME)-C)\d{4}|catalyst|CIGESM', re.M | re.I):
      type = "Switch"
    if first_match(conn, r'\bC1200\b|\bAIR'):
      type = "Wireless Access Point"

    model = first_match(conn, r'cisco ((?:WS-C|Cat|AS|C|VG)?\d{3,4}\S*\b)\S*\b', re.M | re.I)

    serial_number = first_match(conn, r'^Processor\s+board\s+ID\s+(\w+)')

    return [model, serial_number, type, version]
Пример #22
0
def extract(
    host,
    username,
    tar_file,
    cd_dir,
    timeout=45,
    key_filename=None,
    verbosity=0,
    parallel_count=5,
):
    """Extract and start lab"""

    log.debug('Extracting and starting lab on %s' % host)
    log.info('Extracting and starting Netkit lab')
    from Exscript import Account
    from Exscript.util.start import start
    from Exscript.util.match import first_match
    from Exscript import PrivateKey
    from Exscript.protocols.Exception import InvalidCommandException

    messaging = ank_messaging

    def starting_host(protocol, index, data):
        log.info('Starting %s' % data.group(1))

    def lab_started(protocol, index, data):
        log.info('Lab started on %s' % host)

    def make_not_found(protocol, index, data):
        log.warning(
            'Make not installed on remote host %s. Please install make and retry.'
            % host)
        return

    def process_vlist(response):
        """Obtain VM to PID listing: required if terminating a numeric VM"""

        # TODO: could process using textfsm template

        vm_to_pid = {}
        for line in response.splitlines():
            match = re.match(r'^\w+\s+(\w+)\s+(\d+)', line)
            if match:
                vm = match.group(1)
                pid = match.group(2)
                vm_to_pid[vm] = pid

        return vm_to_pid

    def start_lab(thread, host, conn):
        conn.set_timeout(timeout)
        conn.add_monitor(r'Starting "(\w+)"', starting_host)
        conn.add_monitor(r'The lab has been started', lab_started)
        lab_vlist = []

        # conn.add_monitor(r'Virtual machine "((\S*_*)+)" is already running. Please', already_running_b)

        conn.add_monitor(r'make: not found', make_not_found)

        # conn.data_received_event.connect(data_received)

        conn.execute('cd %s' % cd_dir)
        conn.execute('lcrash -k')
        conn.execute('lclean')
        conn.execute('cd')  # back to home directory tar file copied to
        conn.execute('tar -xzf %s' % tar_file)
        conn.execute('cd %s' % cd_dir)

        conn.execute('linfo')
        linfo_response = str(conn.response)
        vm_list = []
        for line in linfo_response.splitlines():
            if 'The lab is made up of' in line:
                open_bracket = line.index('(')
                close_bracket = line.index(')')
                vm_list = line[open_bracket + 1:close_bracket]
                vm_list = vm_list.split()
                log.info('The lab contains VMs %s' % ', '.join(vm_list))

        # now check if any vms are still running

        conn.execute('vlist')
        response = str(conn.response)
        lab_vlist = process_vlist(response)

        for virtual_machine in lab_vlist:
            if virtual_machine in vm_list:
                if virtual_machine.isdigit:

                    # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID)

                    crash_id = lab_vlist.get(virtual_machine)
                else:
                    crash_id = virtual_machine  # use name

                if crash_id:

                    # crash_id may not be set, if machine not present in initial vlist, if so then ignore

                    log.info('Stopping running VM %s' % virtual_machine)
                    conn.execute('vcrash %s' % crash_id)

        conn.execute('vlist')
        conn.execute('lclean')
        start_command = 'lstart -p%s -o --con0=none' % parallel_count
        lab_is_started = False
        while lab_is_started == False:
            try:
                log.info('Starting lab')
                conn.execute(start_command)
            except InvalidCommandException, error:
                error_string = str(error)
                if 'already running' in error_string:

                    conn.execute('vlist')
                    response = str(conn.response)
                    lab_vlist = process_vlist(response)

                    running_vms = []
                    for line in error_string.splitlines():
                        if 'already running' in line:
                            running_vm = line.split('"')[1]
                            running_vms.append(running_vm)

                    for virtual_machine in running_vms:
                        if virtual_machine.isdigit:

                            # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID)

                            crash_id = lab_vlist.get(virtual_machine)
                        else:
                            crash_id = virtual_machine  # use name

                        if crash_id:

                            # crash_id may not be set, if machine not present in initial vlist, if so then ignore

                            log.info('Stopping running VM %s' %
                                     virtual_machine)
                            conn.execute('vcrash %s' % crash_id)

                    time.sleep(1)
            else:

                # conn.execute(start_command)

                lab_is_started = True
        first_match(conn, r'^The lab has been started')
        log.info('Lab started'
                 )  # TODO: make this captured - need to debug capturing
        conn.send('exit')
Пример #23
0
def extract(host, username, tar_file, cd_dir, timeout = 30, key_filename = None):
    """Extract and start lab"""
    from Exscript import Account
    from Exscript.util.start import start
    from Exscript.util.match import first_match
    from Exscript import PrivateKey
    from Exscript.protocols.Exception import InvalidCommandException


    import pika
    import json
    www_connection = pika.BlockingConnection(pika.ConnectionParameters(
            host='115.146.94.68'))
    www_channel = www_connection.channel()

    www_channel.exchange_declare(exchange='www',
            type='direct')


    def starting_host(protocol, index, data):
        #print "Starting", data.group(index)
        log.info(data.group(index))
        body = {"starting": data.group(index)}
        www_channel.basic_publish(exchange='www',
                routing_key = "client",
                body= json.dumps(body))
        pass
#TODO: send to rabbitmq

    def lab_started(protocol, index, data):
        print "Lab started"

    def do_something(thread, host, conn):
        conn.set_timeout(timeout)
        conn.add_monitor(r'Starting (\S+)', starting_host)
        conn.add_monitor(r'The lab has been started', lab_started)
        #conn.data_received_event.connect(data_received)
        conn.execute('cd %s' % cd_dir)
        conn.execute('lcrash -k')
        conn.execute("lclean")
        conn.execute('cd') # back to home directory tar file copied to
        conn.execute('tar -xzf %s' % tar_file)
        conn.execute('cd %s' % cd_dir)
        conn.execute('vlist')
        conn.execute("lclean")
        log.info("Starting lab")
        start_command = 'lstart -p5 -o --con0=none'
        try:
            conn.execute(start_command)
        except InvalidCommandException, error:
            if "already running" in str(error):
                time.sleep(1)
                #print "Already Running" #TODO: handle appropriately
                #print "Halting previous lab"
                #conn.execute("vclean -K")
                #print "Halted previous lab"
                #conn.execute("vstart taptunnelvm --con0=none --eth0=tap,172.16.0.1,172.16.0.2") # TODO: don't hardcode this
                #print "Starting lab"
                conn.execute(start_command)
        first_match(conn, r'^The lab has been started')
        conn.send("exit")
Пример #24
0
def extract(
    host,
    username,
    tar_file,
    cd_dir,
    timeout=45,
    key_filename=None,
    verbosity=0,
    parallel_count=5,
    ):
    """Extract and start lab"""

    log.debug('Extracting and starting lab on %s' % host)
    log.info('Extracting and starting Netkit lab')
    from Exscript import Account
    from Exscript.util.start import start
    from Exscript.util.match import first_match
    from Exscript import PrivateKey
    from Exscript.protocols.Exception import InvalidCommandException

    messaging = ank_messaging

    def starting_host(protocol, index, data):
        log.info('Starting %s' % data.group(1))

    def lab_started(protocol, index, data):
        log.info('Lab started on %s' % host)

    def make_not_found(protocol, index, data):
        log.warning('Make not installed on remote host %s. Please install make and retry.'
                     % host)
        return

    def process_vlist(response):
        """Obtain VM to PID listing: required if terminating a numeric VM"""

        # TODO: could process using textfsm template

        vm_to_pid = {}
        for line in response.splitlines():
            match = re.match(r'^\w+\s+(\w+)\s+(\d+)', line)
            if match:
                vm = match.group(1)
                pid = match.group(2)
                vm_to_pid[vm] = pid

        return vm_to_pid

    def start_lab(thread, host, conn):
        conn.set_timeout(timeout)
        conn.add_monitor(r'Starting "(\w+)"', starting_host)
        conn.add_monitor(r'The lab has been started', lab_started)
        lab_vlist = []

        # conn.add_monitor(r'Virtual machine "((\S*_*)+)" is already running. Please', already_running_b)

        conn.add_monitor(r'make: not found', make_not_found)

        # conn.data_received_event.connect(data_received)

        conn.execute('cd %s' % cd_dir)
        conn.execute('lcrash -k')
        conn.execute('lclean')
        conn.execute('cd')  # back to home directory tar file copied to
        conn.execute('tar -xzf %s' % tar_file)
        conn.execute('cd %s' % cd_dir)

        conn.execute('linfo')
        linfo_response = str(conn.response)
        vm_list = []
        for line in linfo_response.splitlines():
            if 'The lab is made up of' in line:
                open_bracket = line.index('(')
                close_bracket = line.index(')')
                vm_list = line[open_bracket + 1:close_bracket]
                vm_list = vm_list.split()
                log.info('The lab contains VMs %s' % ', '.join(vm_list))

        # now check if any vms are still running

        conn.execute('vlist')
        response = str(conn.response)
        lab_vlist = process_vlist(response)

        for virtual_machine in lab_vlist:
            if virtual_machine in vm_list:
                if virtual_machine.isdigit:

                    # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID)

                    crash_id = lab_vlist.get(virtual_machine)
                else:
                    crash_id = virtual_machine  # use name

                if crash_id:

                    # crash_id may not be set, if machine not present in initial vlist, if so then ignore

                    log.info('Stopping running VM %s' % virtual_machine)
                    conn.execute('vcrash %s' % crash_id)

        conn.execute('vlist')
        conn.execute('lclean')
        start_command = 'lstart -p%s -o --con0=none' % parallel_count
        lab_is_started = False
        while lab_is_started == False:
            try:
                log.info('Starting lab')
                conn.execute(start_command)
            except InvalidCommandException, error:
                error_string = str(error)
                if 'already running' in error_string:

                    conn.execute('vlist')
                    response = str(conn.response)
                    lab_vlist = process_vlist(response)

                    running_vms = []
                    for line in error_string.splitlines():
                        if 'already running' in line:
                            running_vm = line.split('"')[1]
                            running_vms.append(running_vm)

                    for virtual_machine in running_vms:
                        if virtual_machine.isdigit:

                            # convert to PID if numeric, as vcrash can't crash numeric ids (treats as PID)

                            crash_id = lab_vlist.get(virtual_machine)
                        else:
                            crash_id = virtual_machine  # use name

                        if crash_id:

                            # crash_id may not be set, if machine not present in initial vlist, if so then ignore

                            log.info('Stopping running VM %s'
                                    % virtual_machine)
                            conn.execute('vcrash %s' % crash_id)

                    time.sleep(1)
            else:

                    # conn.execute(start_command)

                lab_is_started = True
        first_match(conn, r'^The lab has been started')
        log.info('Lab started')  # TODO: make this captured - need to debug capturing
        conn.send('exit')