Ejemplo n.º 1
0
def Upload_conf(input,
                hostname,
                username,
                password,
                mode="telnet",
                port=23,
                commant="Commited by NetConf"):

    # Connect to the Host

    try:
        dev = Device(host=hostname,
                     user=username,
                     passwd=password,
                     mode=mode,
                     port=port)
        dev.open()

    except Exception as err:
        sys.exit(1)

    dev.bind(cu=Config)

    # Load configuration changes

    print(bcolors.OKBLUE + "Loading configuration changes" + bcolors.ENDC)

    try:
        dev.cu.load(input, merge=True)

    except (ConfigLoadError, Exception) as err:
        print(bcolors.WARNING +
              "Unable to load configuration changes: {0}".format(err) +
              bcolors.ENDC)
        return

    # Commit the configuration

    print(bcolors.OKGREEN + "Committing the configuration" + bcolors.ENDC)

    try:
        dev.cu.commit(comment=commant)

    except CommitError as err:
        print(bcolors.WARNING +
              "Unable to commit configuration: {0}".format(err) + bcolors.ENDC)
        dev.close()
        return False

    except ConnectionResetError as err:
        return False

    except RuntimeError as err:
        print(bcolors.WARNING + "Unable to connect: {0}".format(err) +
              bcolors.ENDC)
        return False

    print(bcolors.OKGREEN + "Configuration commited" + bcolors.ENDC)
    return True
    """
Ejemplo n.º 2
0
def main():
    dev = Device(host=host, user=user, password=password)
    try:
        dev.open()
    except Exception as err:
        print("Cannot connect to device: {}".format(err))
        return

    dev.bind(cu=Config)

    # Lock the configuration, load changes, commit
    print("Locking the configuration on: {}".format(host))
    try:
        dev.cu.lock()
    except LockError:
        print("Error: Unable to lock configuration on: {}".format(host))
        dev.close()
        return

    print("Loading configuration changes on: {}".format(host))
    try:
        dev.cu.load(template=j2_template,
                    template_vars=vars,
                    format='text',
                    merge=True)
    except ValueError as err:
        print(err.message)
    except Exception as err:
        if err.rsp.find('.//ok') is None:
            rpc_msg = err.rsp.findtext('.//error-message')
            print("Unable to load config changes: {}".format(rpc_msg))

        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Error: Unable to unlock configuration")
        dev.close()
        return
    print("Committing the configuration on: {}".format(host))
    try:
        dev.cu.commit()
        # print dev.cu.diff()
    except CommitError:
        print("Error: Unable to commit configuration")
        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Error: Unable to unlock configuration")
        dev.close()
        return

    print("Unlocking the configuration")
    try:
        dev.cu.unlock()
    except UnlockError:
        print("Error: Unable to unlock configuration")

    dev.close()
Ejemplo n.º 3
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko,
                              mock_connect, mock_proxy):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_any()
Ejemplo n.º 4
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko, mock_connect, mock_proxy):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_any()
Ejemplo n.º 5
0
def load_merge_config(Deivces, config_file):
    for device in Deivces:
        try:
            dev = Device(host=device['host_IP'],
                         user=device['usr'],
                         passwd=device['pwd'])
            dev.open()
        except ConnectError as err:
            print(device['host_IP'] +
                  ":Cannot connect to device: {0}".format(err))
            return
        dev.bind(cu=Config)

        print(device['host_IP'] + ":Locking the configuration")
        try:
            dev.cu.lock()
        except LockError as err:
            print(device['host_IP'] +
                  ":Unable to lock configuration: {0}".format(err))
            dev.close()
            return

        print(device['host_IP'] + "::Loading configuration changes")
        try:
            dev.cu.load(path=config_file, merge=True)
        except (ConfigLoadError, Exception) as err:
            print(device['host_IP'] +
                  ":Unable to load configuration changes: {0}".format(err))
            print(device['host_IP'] + ":Unlocking the configuration")
            try:
                dev.cu.unlock()
            except UnlockError:
                print(device['host_IP'] +
                      ":Unable to unlock configuration: {0}".format(err))
            dev.close()
            return

        print(device['host_IP'] + ":Committing the configuration")
        try:
            dev.cu.commit()
        except CommitError as err:
            print(device['host_IP'] +
                  ":Unable to commit configuration: {0}".format(err))
            print(device['host_IP'] + ":Unlocking the configuration")
            try:
                dev.cu.unlock()
            except UnlockError as err:
                print(device['host_IP'] +
                      ":Unable to unlock configuration: {0}".format(err))
            dev.close()
            return

        print(device['host_IP'] + ":Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError as err:
            print(device['host_IP'] +
                  ":Unable to unlock configuration: {0}".format(err))
        dev.close()
    return
Ejemplo n.º 6
0
def main(argv):
    sys.stdout.write("commitment\n\n")
    if len(sys.argv) != 2:
        sys.stdout.write("Error: Missing parameter\n")
        sys.stdout.write("Usage: commitment.py <device-list.txt>\n")
        sys.exit()
    username = raw_input('Username: '******'Password (leave blank to use SSH Key): ')
    hostsfile = open(str(sys.argv[1]),'r')
    for address in hostsfile:
		if password != '':
			dev = Device(host=address.rstrip('\n'),user=username,passwd=password)
		else:
			dev = Device(host=address.rstrip('\n'),user=username)
		print "Opening :" + str(dev.hostname)
		dev.open()
		print "Opened :" + str(dev.hostname)
		print "Opening config"
		dev.bind(cf=Config)
		print "Locking config"
		dev.cf.lock()
		print "Committing config"
		dev.cf.commit()
		print "Unlocking config"
		dev.cf.unlock
		print "Closing: " + str(dev.hostname)
		dev.close()
		print "Closed :" + str(dev.hostname)
    hostsfile.close()
Ejemplo n.º 7
0
def main(argv):
    sys.stdout.write("commitment\n\n")
    if len(sys.argv) != 2:
        sys.stdout.write("Error: Missing parameter\n")
        sys.stdout.write("Usage: commitment.py <device-list.txt>\n")
        sys.exit()
    username = raw_input('Username: '******'Password (leave blank to use SSH Key): ')
    hostsfile = open(str(sys.argv[1]), 'r')
    for address in hostsfile:
        if password != '':
            dev = Device(host=address.rstrip('\n'),
                         user=username,
                         passwd=password)
        else:
            dev = Device(host=address.rstrip('\n'), user=username)
        print "Opening :" + str(dev.hostname)
        dev.open()
        print "Opened :" + str(dev.hostname)
        print "Opening config"
        dev.bind(cf=Config)
        print "Locking config"
        dev.cf.lock()
        print "Committing config"
        dev.cf.commit()
        print "Unlocking config"
        dev.cf.unlock
        print "Closing: " + str(dev.hostname)
        dev.close()
        print "Closed :" + str(dev.hostname)
    hostsfile.close()
Ejemplo n.º 8
0
def main():
    # open a connection with the device and start a NETCONF session
    try:
        dev = Device(host=host,user=user,ssh_private_key_file=privateKey)
        print ("Connecting...")
        dev.open()
        print ("Connected.")

        dev.bind(cu=Config)

        # Lock the configuration, load configuration changes, and commit
        print ("Locking the configuration")
        dev.cu.lock()

        print ("Loading configuration changes")
        #dev.cu.load(path=conf_file, merge=True)
        dev.cu.load(cmd, merge=True)

        print ("Diff")
        dev.cu.pdiff() 

        print ("Committing the configuration")
        dev.cu.commit(comment='Loaded by example.')

        print ("Unlocking the configuration")
        dev.cu.unlock()



    except ConnectError as err:
        print ("Cannot connect to device: {0}".format(err))

    except LockError as err:
        print ("Unable to lock configuration: {0}".format(err))

    except (ConfigLoadError, Exception) as err:
        print ("Unable to load configuration changes: {0}".format(err))
        print ("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print ("Unable to unlock configuration: {0}".format(err))

    except CommitError as err:
        print ("Unable to commit configuration: {0}".format(err))
        print ("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError as err:
            print ("Unable to unlock configuration: {0}".format(err))

    except UnlockError as err:
        print ("Unable to unlock configuration: {0}".format(err))



    # End the NETCONF session and close the connection
    dev.close()
Ejemplo n.º 9
0
def main():
    dev = Device(host=host, user=user, password=password)
    try:
        dev.open()
    except Exception as err:
        print("Cannot connect to device: {}".format(err))
        return

    dev.bind(cu=Config)

    # Lock the configuration, load changes, commit
    print("Locking the configuration on: {}".format(host))
    try:
        dev.cu.lock()
    except LockError:
        print("Error: Unable to lock configuration on: {}".format(host))
        dev.close()
        return

    print("Loading configuration changes on: {}".format(host))
    try:
        dev.cu.load(template=j2_template,
                    template_vars=vars, format='text', merge=True)
    except ValueError as err:
        print(err.message)
    except Exception as err:
        if err.rsp.find('.//ok') is None:
            rpc_msg = err.rsp.findtext('.//error-message')
            print("Unable to load config changes: {}".format(rpc_msg))

        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Error: Unable to unlock configuration")
        dev.close()
        return
    print("Committing the configuration on: {}".format(host))
    try:
        dev.cu.commit()
        # print dev.cu.diff()
    except CommitError:
        print("Error: Unable to commit configuration")
        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Error: Unable to unlock configuration")
        dev.close()
        return

    print("Unlocking the configuration")
    try:
        dev.cu.unlock()
    except UnlockError:
        print("Error: Unable to unlock configuration")

    dev.close()
Ejemplo n.º 10
0
class JunOSDriver(NetworkDriver):

    def __init__(self, hostname, username, password):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.device = Device(hostname, user=username, password=password)
        self.config_replace = False

    def open(self):
        self.device.open()
        self.device.bind(cu=Config)
        self.device.cu.lock()

    def close(self):
        self.device.cu.unlock()
        self.device.close()

    def _load_candidate(self, filename, config, overwrite):
        if filename is None:
            configuration = config
        else:
            with open(filename) as f:
                configuration = f.read()

        try:
            self.device.cu.load(configuration, format='text', overwrite=overwrite)
        except ConfigLoadError as e:
            if self.config_replace:
                raise ReplaceConfigException(e.message)
            else:
                raise MergeConfigException(e.message)

    def load_replace_candidate(self, filename=None, config=None):
        self.config_replace = True
        self._load_candidate(filename, config, True)

    def load_merge_candidate(self, filename=None, config=None):
        self.config_replace = False
        self._load_candidate(filename, config, False)

    def compare_config(self):
        diff = self.device.cu.diff()

        if diff is None:
            return ''
        else:
            return diff

    def commit_config(self):
        self.device.cu.commit()

    def discard_config(self):
        self.device.cu.rollback(rb_id=0)

    def rollback(self):
        self.device.cu.rollback(rb_id=1)
        self.commit_config()
Ejemplo n.º 11
0
def fnWriteToDevice(sConfiguration):
    logging.debug("fnWriteToDevice:")
    hDev = Device()
    hDev.open()
    hDev.bind(sCu=Config)
    #
    # Lock the configuration, load configuration changes, and commit
    #    logging.info("fnWriteToDevice: Locking the configuration")
    #    try:
    #        sCu.lock()
    #        logging.debug("fnWriteToDevice: Configuration Locked")
    #    except LockError:
    #        logging.debug("fnWriteToDevice: Error: Unable to lock configuration")
    #        hDev.close()
    #        return
    #
    #    logging.info("fnWriteToDevice: Loading configuration changes")
    #    try:
    #        sCu.load(sConfiguration, format = "set", ignore_warning="statement not found")
    #        logging.debug("fnWriteToDevice: Configuration Loaded")
    #    except ConfigLoadError as err:
    #        logging.debug("fnWriteToDevice: " + err)
    #        logging.debug("fnWriteToDevice: UNABLE TO LOAD CONFIGURATION CHANGES:")
    #        logging.debug("fnWriteToDevice: UNLOCKING THE CONFIGURATION")
    #        try:
    #           sCu.unlock()
    #           logging.debug("fnWriteToDevice: Unlocking from Load Failure")
    #        except UnlockError:
    #           logging.debug("fnWriteToDevice: Error: Unable to unlock configuration from Load Failure")
    #        sDev.close()
    #        return
    #
    #    logging.info("fnWriteToDevice: Committing the configuration")
    #    try:
    #        hDev.sCu.commit()
    #        logging.debug("fnWriteToDevice: Commiting Configuration")
    #        logging.debug("fnWriteToDevice: " + sConfiguration)
    #    except CommitError:
    #        logging.debug("fnWriteToDevice: Error: Unable to commit configuration")
    #        try:
    #           sCu.unlock()
    #           logging.debug("fnWriteToDevice: Unlocking from Commit Failure")
    #        except UnlockError:
    #            logging.debug("fnWriteToDevice: Error: Unable to unlock configuration from Commit Failure")
    #        hDev.close()
    #        logging.debug("fnWriteToDevice: Close Device Connection")
    #        return
    #
    #    logging.debug("fnWriteToDevice: Unlocking the configuration")
    #    try:
    #         hDev.sCu.unlock()
    #         logging.debug("fnWriteToDevice: Unlocking configuration")
    #    except UnlockError:
    #         logging.debug("fnWriteToDevice: Error: Unable to unlock configuration")
    #
    hdev.close()
    return
Ejemplo n.º 12
0
def rollback(hostname):
    dev = Device(hostname, user='******', password='******')
    dev.open(gather_facts=False)
    dev.timeout = 60
    dev.bind(cu=Config)
    with Config(dev, mode='private') as cu:
        cu.rollback(1)
        cu.commit()
        print('{} - Done'.format(hostname))
    dev.close()
Ejemplo n.º 13
0
def customize(hostip, switchvars, templatefile="access_switch.j2"):
    dev = Device(user="******", host=hostip, password="******")
    dev.open()
 
    dev.bind(cu=Config)
    dev.cu
    print "Loading template onto: {0} (SN: {1}) @ {2}".format(switchvars['hostname'], switchvars['serial_number'], switchvars['mgmt_ip'])

    dev.cu.load(template_path=templatefile, template_vars=switchvars, format="set")
    dev.cu.commit()
    dev.close()
def groups_apply_by_cli(hostname, username, password, cli):
    # open a connection with the device and start a NETCONF session
    try:
        dev = Device(host=hostname, username=username, password=password)
        dev.open()
        dev.timeout = 300
    except ConnectError as err:
        print("Cannot connect to device: {0}".format(err))
        return
    dev.bind(cu=Config)
    # Lock the configuration, load configuration changes, and commit
    print("Locking the configuration")
    try:
        dev.cu.lock()
    except LockError as err:
        print("Unable to lock configuration: {0}".format(err))
        dev.close()
        return
    try:
        dev.cu.load(cli, format='set', ignore_warning=True)
        dev.cu.pdiff()
    except (ConfigLoadError, Exception) as err:
        print("Unable to load configuration changes: {0}".format(err))
        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Unable to unlock configuration: {0}".format(err))
        dev.close()
        return

    print("Committing the configuration")
    try:
        dev.cu.commit_check()
        dev.cu.commit(confirm=1, comment='Apply service group configurations')
        dev.cu.commit(
            comment='Confirm commit by PyEZ SQT Auto-provisioning Tool.',
            timeout=60)
    except CommitError as err:
        print("Unable to commit configuration: {0}".format(err))
        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError as err:
            print("Unable to unlock configuration: {0}".format(err))
            dev.close()
            return
    print("Unlocking the configuration")
    try:
        dev.cu.unlock()
    except UnlockError as err:
        print("Unable to unlock configuration: {0}".format(err))
    # End the NETCONF session and close the connection
    dev.close()
Ejemplo n.º 15
0
def main():
    # open a connection with the device and start a NETCONF session
    try:
        dev = Device(host=host,user=user,password=password)
        dev.open()
    except ConnectError as err:
        print ("Cannot connect to device: {0}".format(err))
        return

    dev.bind(cu=Config)

    # Lock the configuration, load configuration changes, and commit
    print ("Locking the configuration")
    try:
        dev.cu.lock()
    except LockError as err:
        print ("Unable to lock configuration: {0}".format(err))
        dev.close()
        return

    print ("Loading configuration changes")
    try:
        dev.cu.load(path=conf_file, merge=True)
    except (ConfigLoadError, Exception) as err:
        print ("Unable to load configuration changes: {0}".format(err))
        print ("Unlocking the configuration")
        try:
                dev.cu.unlock()
        except UnlockError:
            print ("Unable to unlock configuration: {0}".format(err))
        dev.close()
        return

    print ("Committing the configuration")
    try:
        dev.cu.commit(comment='Loaded by example.')
    except CommitError as err:
        print ("Unable to commit configuration: {0}".format(err))
        print ("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError as err:
            print ("Unable to unlock configuration: {0}".format(err))
        dev.close()
        return

    print ("Unlocking the configuration")
    try:
        dev.cu.unlock()
    except UnlockError as err:
        print ("Unable to unlock configuration: {0}".format(err))

    # End the NETCONF session and close the connection
    dev.close()
Ejemplo n.º 16
0
def commit_config(device, config_text):
		dev = Device(host=device, user=username, password=password)
		dev.open()
		dev.bind(cfg=Config)
		try:
			dev.cfg.load(config_text, format="set", merge=True)
		except Exception as err:
		    if err.rsp.find('.//ok') is None:
		        rpc_msg = err.rsp.findtext('.//error-message')
		        return "Error:", rpc_msg			
		dev.cfg.commit()
		dev.close()
		return
Ejemplo n.º 17
0
def commit_config(device, config_text):
    dev = Device(host=device, user=username, password=password)
    dev.open()
    dev.bind(cfg=Config)
    try:
        dev.cfg.load(config_text, format="set", merge=True)
    except Exception as err:
        if err.rsp.find('.//ok') is None:
            rpc_msg = err.rsp.findtext('.//error-message')
            return "Error:", rpc_msg
    dev.cfg.commit()
    dev.close()
    return
def main():
    print 'Start configuration building'
    # YAML file.
    with open(options.data) as fh:
        data = yaml.load(fh.read())

    # Jinja2 template file.
    with open(options.template) as t_fh:
        t_format = t_fh.read()

    for device in data:
        hostname = device[options.key]
        print '  * Start updating ' + hostname
        logger.info('Start updating %s', hostname)
        template = Template(t_format)
        jdev = Device(host=hostname,
                      user=options.username,
                      password=options.password,
                      gather_facts=False)
        jdev.open()
        print "  * Connected to " + hostname
        logger.info('connected to %s', hostname)
        jdev.bind(cu=Config)
        # Execute Rollback to prevent commit change from old config session
        jdev.cu.rollback()
        rsp = jdev.cu.load(template_path=options.template,
                           template_vars=device)

        # Display some informations - Configuration Diff
        # Only if verbose Mode is enable
        if (options.verbose):
            print delimiter_tab + "  * Configuration Diff is :"
            for diff in cleanup_answer(jdev.cu.diff()):
                print delimiter_tab + diff
        # Apply changes if options.safe is not enable. Protect user aginst script error. In case of test, user can emulate script and change w/out impact production
        if options.safe is True:
            print delimiter_tab + '  ** Running in dry-run mode, commit aborted'
            logger.info(
                'Running in DRY-RUN mode, commit aborted and rollback to previsous stage'
            )
            # Execute Rollback to prevent change are loaded and not discraded before next config change
            jdev.cu.rollback()
        else:
            rsp = jdev.cu.commit()
            print delimiter_tab + "  * Commit Complete"
            logger.warning('Dry-run disable, commit complete')
        print("")

    print 'End of Script'
Ejemplo n.º 19
0
def customize(hostip, switchvars, templatefile="access_switch.j2"):
    dev = Device(user="******", host=hostip, password="******")
    dev.open()

    dev.bind(cu=Config)
    dev.cu
    print "Loading template onto: {0} (SN: {1}) @ {2}".format(
        switchvars['hostname'], switchvars['serial_number'],
        switchvars['mgmt_ip'])

    dev.cu.load(template_path=templatefile,
                template_vars=switchvars,
                format="set")
    dev.cu.commit()
    dev.close()
Ejemplo n.º 20
0
def push(hostname, config):
    if args.pp:
        print(config)
    else:
        dev = Device(hostname, user='******', password='******')
        dev.open(gather_facts=False)
        dev.timeout = 60
        dev.bind(cu=Config)
        with Config(dev, mode='private') as cu:
            rsp = cu.load(config, format='text', merge=True)
            diff = show_diff(cu)
            if diff:
                print(diff)
            #    commit(cu)
            cu.rollback()
Ejemplo n.º 21
0
class Manager():
    def __init__(self,host,user,password):
        self.dev = Device(host=host,user=user,password=password)
        self.dev.bind(cu=Config)

    def open(self):
        try:
            self.dev.open()
            print "Connection Open"
        except Exception as err:
            print err

    def close(self):
        try:
            self.dev.close()
            print "Connection Closed"
        except Exception as err:
            print err

    def get_facts(self):
        pprint(self.dev.facts)

    def open_config(self,type):
        try:
            #attempt to open a configuration
            output = self.dev.rpc("<open-configuration><{0}/></open-configuration>".format(type))
            print "Open {0} configuration".format(type)
        except Exception as err:
            #output an error if the configuration is not availble
            print err

    def load_config_template(self,template,template_vars):
        new_template = Template(template)
        final_template = new_template.render(template_vars)

        try:
            output = self.dev.cu.load(final_template,format="text",merge=True)
            print "Load Complete"
        except Exception as err:
            print err

    def commit_config(self):
        try:
            self.dev.rpc.commit_configuration()
            self.dev.rpc.close_configuration()
            print "Commit Complete"
        except Exception as err:
            print err
Ejemplo n.º 22
0
def provision_junos(port, username, password):
    device = Device('127.0.0.1', user=username, port=port)
    device.open()
    device.bind(cu=Config)

    with open('../junos/initial.conf', 'r') as f:
        configuration = f.read()

    device.cu.load(configuration, format='text', overwrite=True)

    try:
        device.cu.commit()
        device.close()
    except jnpr.junos.exception.RpcTimeoutError:
        # This actually means everything went fine
        print_info_message()
Ejemplo n.º 23
0
def provision_junos(port, username, password):
    device = Device('127.0.0.1', user=username, port=port)
    device.open()
    device.bind(cu=Config)

    with open('../junos/initial.conf', 'r') as f:
        configuration = f.read()

    device.cu.load(configuration, format='text', overwrite=True)

    try:
        device.cu.commit()
        device.close()
    except jnpr.junos.exception.RpcTimeoutError:
        # This actually means everything went fine
        print_info_message()
Ejemplo n.º 24
0
def main():
	dev = Device(host='172.27.0.159',user='******',password='******')
    # open a connection with the device and start a NETCONF session
	try:
		dev.open()
	except Exception as err:
		print "Cannot connect to device:", err
		return

	dev.bind( cu=Config )

# Lock the configuration, load configuration changes, and commit
	print "Locking the configuration"
	try:
		dev.cu.lock()
	except LockError:
		print "Error: Unable to lock configuration"
		dev.close()
		return

	print "configuring"
	set_cmd = 'set system login message "Hello, Just testing Python!"'
	print "loading config"
	dev.cu.load(set_cmd, format='set')
	print "Committing the configuration"
	# commit the configuration
	try:
		dev.cu.commit()
	except CommitError:
		print "Error: Unable to commit configuration"
		print "Unlocking the configuration"
        try:
            dev.cu.unlock()
        except UnlockError:
            print "Error: Unable to unlock configuration"
        dev.close()
        return
        
	print "Unlocking the configuration"
	try:
		dev.cu.unlock()
	except UnlockError:
		print "Error: Unable to unlock configuration"

	dev.close()
Ejemplo n.º 25
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko,
                              mock_connect, mock_proxy):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_any()

    def test_scp_progress(self):
        scp = SCP(self.dev)
        print scp._scp_progress('test', 100, 50)

    @contextmanager
    def capture(self, command, *args, **kwargs):
        out, sys.stdout = sys.stdout, StringIO()
        command(*args, **kwargs)
        sys.stdout.seek(0)
        yield sys.stdout.read()
        sys.stdout = out
Ejemplo n.º 26
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko, mock_connect, mock_proxy):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_any()

    def test_scp_progress(self):
        scp = SCP(self.dev)
        print scp._scp_progress('test', 100, 50)

    @contextmanager
    def capture(self, command, *args, **kwargs):
        out, sys.stdout = sys.stdout, StringIO()
        command(*args, **kwargs)
        sys.stdout.seek(0)
        yield sys.stdout.read()
        sys.stdout = out
def main():
    print 'Start configuration building'
    # YAML file.
    with open( options.data ) as fh:
        data = yaml.load( fh.read() )

    # Jinja2 template file.
    with open( options.template ) as t_fh:
        t_format = t_fh.read()

    for device in data:
        hostname = device[ options.key ]
        print '  * Start updating '+hostname
        logger.info('Start updating %s',hostname)
        template = Template( t_format )
        jdev = Device( host=hostname , user=options.username , password=options.password , gather_facts=False)
        jdev.open()
        print "  * Connected to "+ hostname
        logger.info('connected to %s',hostname)
        jdev.bind( cu=Config )
        # Execute Rollback to prevent commit change from old config session
        jdev.cu.rollback()
        rsp = jdev.cu.load( template_path = options.template, template_vars = device)

        # Display some informations - Configuration Diff
        # Only if verbose Mode is enable
        if( options.verbose ):
            print delimiter_tab+"  * Configuration Diff is :"
            for diff in cleanup_answer( jdev.cu.diff() ):
                print delimiter_tab+diff
        # Apply changes if options.safe is not enable. Protect user aginst script error. In case of test, user can emulate script and change w/out impact production
        if options.safe is True:
            print delimiter_tab+'  ** Running in dry-run mode, commit aborted'
            logger.info('Running in DRY-RUN mode, commit aborted and rollback to previsous stage')
            # Execute Rollback to prevent change are loaded and not discraded before next config change
            jdev.cu.rollback()
        else:
            rsp = jdev.cu.commit()
            print delimiter_tab+"  * Commit Complete"
            logger.warning('Dry-run disable, commit complete')
        print ("")

    print 'End of Script'
Ejemplo n.º 28
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
Ejemplo n.º 29
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertIsNone(self.dev.scp.close())

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
Ejemplo n.º 30
0
def upload_config(obj, config_path, vsrx_ip, vsrx_user, vsrx_pass):
    """Upload and commit configuration for VSRX.

    :param obj: test case object
    :type obj: object
    :param config_path: path to vsrx conf file
    :type config_path: string
    :param vsrx_ip: vsrx ip address
    :type vsrx_ip: string
    :param vsrx_user: username for vsrx
    :type vsrx_user: string
    :param vsrx_pass: password for vsrx
    :type vsrx_pass: string
    """

    jun_gw = Device(host=vsrx_ip, user=vsrx_user, password=vsrx_pass)

    for i in range(10):
        try:
            jun_gw.open()
        except ConnectTimeoutError:
            time.sleep(15)
            continue
        else:
            break
    else:
        logger.info("Configuration of vsrx failed. Check router")
        return False

    jun_gw.bind(cu=Config)
    logger.info("Loading config file")
    jun_gw.cu.load(path=config_path)
    logger.info("Checking configuration...")
    if jun_gw.cu.commit_check():
        logger.info("New config was verified")
        jun_gw.cu.commit()
        logger.info("New config was commited")
    else:
        logger.info("Wrong configuration")
        jun_gw.cu.rollback()
    jun_gw.close()
Ejemplo n.º 31
0
def upgrade_os():
      upgrade_host = request.form.getlist('upgrade_srx')
      reboot_list = request.form.getlist('optradio')
      file = request.files['file']
      filename = secure_filename(file.filename)
      print "Upgrade hosts are: ", upgrade_host
      print "Reboot options are: ", reboot_list
      print "Upgrade image: ", filename
      print "update_list", update_list
      for i in upgrade_host:
           for j in update_list:
               if i in j:
                    hostname = j[0]
                    usr = j[1]
                    psswd = j[2]
                    dev = Device(hostname, user=usr, password=psswd)
                    dev.open()
                    dev.bind(sw=SW)
                    upgrade_file = "images/"+filename
                    flash(dev.sw.install(package = upgrade_file, progress = my_progress))
      return render_template('/add_device.html')
Ejemplo n.º 32
0
def addconfig(Config_File):
    dev = Device(host=hostName, user=uName, password=uPass)
    dev.open()
    dev.bind(cu=Config)
    print("#=" * 40)
    print("binding the device to configuration mode")
    print("#=" * 40)

    try:
        # Lock the configuration, load configuration changes, and commit
        dev.cu.lock()
        print("Strep:1 ==> Locking the configuration")
    except LockError as err:
        dev.close()
        print("Step:1 ==> Unable to lock configuration: {0}".format(err))

    try:
        dev.cu.load(template_path=Config_File, format="set", merge=True)
        print(
            "Step2: ==> Loading configuration changes : Adding command for Routing Engine Redundancy"
        )
    except (ConfigLoadError, Exception) as err:
        print(
            "Step2: ==> Unable to load configuration changes: {0}".format(err))

    try:
        dev.cu.commit(comment='Juniper JUNOS Device Upgrade')
        print(
            "Step3: ==> Committing the configuration : Routing Engine Redundancy Commands Added"
        )
    except CommitError as err:
        print("Step3: ==> Unable to commit configuration: {0}".format(err))

    try:
        dev.cu.unlock()
        print("Step4: ==> Unlocking the configuration")
    except UnlockError as err:
        print("Step4: ==> Unable to unlock configuration: {0}".format(err))

    dev.close()
Ejemplo n.º 33
0
def push(hostname, config):
    if args.pp:
        print(config)
    else:
        dev = Device(hostname, user='******', password='******')
        dev.open(gather_facts=False)
        dev.timeout = 60
        dev.bind(cu=Config)
        with Config(dev, mode='private') as cu:
            cu.load(
                'delete policy-options policy-statement EVPN-host-routes term default'
            )
            cu.load(config, format='text', merge=True)
            cu.load(
                'set policy-options policy-statement EVPN-host-routes term default then reject'
            )
            diff = show_diff(cu)
            if diff:
                print(diff)
                commit(cu)
            #cu.rollback()
        dev.close()
Ejemplo n.º 34
0
class JunOSDriver(NetworkDriver):

    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.timeout = timeout
        self.config_replace = False
        self.locked = False

        if optional_args is None:
            optional_args = {}
        self.port = optional_args.get('port', 22)
        self.config_lock = optional_args.get('config_lock', True)

        self.device = Device(hostname, user=username, password=password, port=self.port)

    def open(self):
        try:
            self.device.open()
        except ConnectTimeoutError as cte:
            raise ConnectionException(cte.message)
        self.device.timeout = self.timeout
        self.device.bind(cu=Config)
        if self.config_lock:
            self.lock()

    def close(self):
        if self.config_lock:
            self.unlock()
        self.device.close()

    def lock(self):
        if not self.locked:
            self.device.cu.lock()
            self.locked = True

    def unlock(self):
        if self.locked:
            self.device.cu.unlock()
            self.locked = False

    def _load_candidate(self, filename, config, overwrite):
        if filename is None:
            configuration = config
        else:
            with open(filename) as f:
                configuration = f.read()

        if not self.config_lock:
            # if not locked during connection time
            # will try to lock it if not already aquired
            self.lock()
            # and the device will be locked till first commit/rollback

        try:
            self.device.cu.load(configuration, format='text', overwrite=overwrite)
        except ConfigLoadError as e:
            if self.config_replace:
                raise ReplaceConfigException(e.message)
            else:
                raise MergeConfigException(e.message)

    def load_replace_candidate(self, filename=None, config=None):
        self.config_replace = True
        self._load_candidate(filename, config, True)

    def load_merge_candidate(self, filename=None, config=None):
        self.config_replace = False
        self._load_candidate(filename, config, False)

    def compare_config(self):
        diff = self.device.cu.diff()

        if diff is None:
            return ''
        else:
            return diff.strip()

    def commit_config(self):
        self.device.cu.commit()
        if not self.config_lock:
            self.unlock()

    def discard_config(self):
        self.device.cu.rollback(rb_id=0)
        if not self.config_lock:
            self.unlock()

    def rollback(self):
        self.device.cu.rollback(rb_id=1)
        self.commit_config()


    # perhaps both should be moved in napalm_base.helpers at some point
    @staticmethod
    def _find_txt(xml_tree, path, default = ''):
        try:
            return xml_tree.find(path).text.strip()
        except Exception:
            return default


    @staticmethod
    def _convert(to, who, default = u''):
        if who is None:
            return default
        try:
            return to(who)
        except:
            return default


    def get_facts(self):

        output = self.device.facts

        uptime = 0
        if 'RE0' in output:
            uptime = output['RE0']['up_time']

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()
        interface_list = interfaces.keys()

        return {
            'vendor': u'Juniper',
            'model': unicode(output['model']),
            'serial_number': unicode(output['serialnumber']),
            'os_version': unicode(output['version']),
            'hostname': unicode(output['hostname']),
            'fqdn': unicode(output['fqdn']),
            'uptime': string_parsers.convert_uptime_string_seconds(uptime),
            'interface_list': interface_list
        }

    def get_interfaces(self):

        # init result dict
        result = {}

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()

        # convert all the tuples to our pre-defined dict structure
        for iface in interfaces.keys():
            result[iface] = {
                'is_up': interfaces[iface]['is_up'],
                'is_enabled': interfaces[iface]['is_enabled'],
                'description': (interfaces[iface]['description'] or u''),
                'last_flapped': float((interfaces[iface]['last_flapped'] or -1)),
                'mac_address': unicode((interfaces[iface]['mac_address'] or '')),
                'speed': -1
            }
            # result[iface]['last_flapped'] = float(result[iface]['last_flapped'])

            match = re.search(r'(\d+)(\w*)', interfaces[iface]['speed'] or u'')
            if match is None:
                continue
            speed_value = self._convert(int, match.group(1), -1)
            if speed_value == -1:
                continue
            speed_unit = match.group(2)
            if speed_unit.lower() == 'gbps':
                speed_value *= 1000
            result[iface]['speed'] = speed_value

        return result

    def get_interfaces_counters(self):
        query = junos_views.junos_iface_counter_table(self.device)
        query.get()
        interface_counters = dict()
        for interface, counters in query.items():
            interface_counters[interface] = {k: v if v is not None else -1 for k, v in counters}
        return interface_counters

    def get_environment(self):
        environment = junos_views.junos_enviroment_table(self.device)
        routing_engine = junos_views.junos_routing_engine_table(self.device)
        temperature_thresholds = junos_views.junos_temperature_thresholds(self.device)
        environment.get()
        routing_engine.get()
        temperature_thresholds.get()
        environment_data = dict()

        for sensor_object, object_data in environment.items():
            structured_object_data = {k: v for k, v in object_data}

            if structured_object_data['class'] == 'Power':
                # Create a dict for the 'power' key
                try:
                    environment_data['power'][sensor_object] = dict()
                except KeyError:
                    environment_data['power'] = dict()
                    environment_data['power'][sensor_object] = dict()

                # Set these values to -1, because Junos does not provide them
                environment_data['power'][sensor_object]['capacity'] = -1.0
                environment_data['power'][sensor_object]['output'] = -1.0

            if structured_object_data['class'] == 'Fans':
                # Create a dict for the 'fans' key
                try:
                    environment_data['fans'][sensor_object] = dict()
                except KeyError:
                    environment_data['fans'] = dict()
                    environment_data['fans'][sensor_object] = dict()

            if structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Power':
                # If status is Failed, Absent or Testing, set status to False.
                environment_data['power'][sensor_object]['status'] = True

            elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Power':
                environment_data['power'][sensor_object]['status'] = False

            elif structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Fans':
                # If status is Failed, Absent or Testing, set status to False.
                environment_data['fans'][sensor_object]['status'] = True

            elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Fans':
                environment_data['fans'][sensor_object]['status'] = False

            for temperature_object, temperature_data in temperature_thresholds.items():
                structured_temperature_data = {k: v for k, v in temperature_data}
                if structured_object_data['class'] == 'Temp':
                    # Create a dict for the 'temperature' key
                    try:
                        environment_data['temperature'][sensor_object] = dict()
                    except KeyError:
                        environment_data['temperature'] = dict()
                        environment_data['temperature'][sensor_object] = dict()

                    environment_data['temperature'][sensor_object]['temperature'] = float(structured_object_data['temperature'])
                    # Set a default value (False) to the key is_critical and is_alert
                    environment_data['temperature'][sensor_object]['is_alert'] = False
                    environment_data['temperature'][sensor_object]['is_critical'] = False
                    # Check if the working temperature is equal to or higher than alerting threshold
                    if structured_temperature_data['red-alarm'] <= structured_object_data['temperature']:
                        environment_data['temperature'][sensor_object]['is_critical'] = True
                        environment_data['temperature'][sensor_object]['is_alert'] = True
                    elif structured_temperature_data['yellow-alarm'] <= structured_object_data['temperature']:
                        environment_data['temperature'][sensor_object]['is_alert'] = True

        for routing_engine_object, routing_engine_data in routing_engine.items():
            structured_routing_engine_data = {k: v for k, v in routing_engine_data}
            # Create dicts for 'cpu' and 'memory'.
            try:
                environment_data['cpu'][routing_engine_object] = dict()
                environment_data['memory'] = dict()
            except KeyError:
                environment_data['cpu'] = dict()
                environment_data['cpu'][routing_engine_object] = dict()
                environment_data['memory'] = dict()
            # Calculate the CPU usage by using the CPU idle value.
            environment_data['cpu'][routing_engine_object]['%usage'] = 100.0 - structured_routing_engine_data['cpu-idle']
            try:
                environment_data['memory']['available_ram'] = int(structured_routing_engine_data['memory-dram-size'])
            except ValueError:
                environment_data['memory']['available_ram'] = int(''.join(i for i in structured_routing_engine_data['memory-dram-size'] if i.isdigit()))
            # Junos gives us RAM in %, so calculation has to be made.
            # Sadly, bacause of this, results are not 100% accurate to the truth.
            environment_data['memory']['used_ram'] = (environment_data['memory']['available_ram'] / 100 * structured_routing_engine_data['memory-buffer-utilization'])

        return environment_data

    @staticmethod
    def _get_address_family(table):
        """
        Function to derive address family from a junos table name
        :params table: The name of the routing table
        :returns: address family
        """
        address_family_mapping = {
            'inet': 'ipv4',
            'inet6': 'ipv6'
        }
        family = table.split('.')[-2]
        return address_family_mapping[family]

    def _parse_route_stats(self, neighbor):
        data = {}
        if not neighbor['is_up']:
            pass
        elif isinstance(neighbor['tables'], list):
            for idx, table in enumerate(neighbor['tables']):
                family = self._get_address_family(table)
                data[family] = {}
                data[family]['received_prefixes'] = neighbor['received_prefixes'][idx]
                data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'][idx]
                data[family]['sent_prefixes'] = neighbor['sent_prefixes'][idx]
        else:
            family = self._get_address_family(neighbor['tables'])
            data[family] = {}
            data[family]['received_prefixes'] = neighbor['received_prefixes']
            data[family]['accepted_prefixes'] = neighbor['accepted_prefixes']
            data[family]['sent_prefixes'] = neighbor['sent_prefixes']
        return data

    @staticmethod
    def _parse_value(value):
        if isinstance(value, basestring):
            return unicode(value)
        elif value is None:
            return u''
        else:
            return value

    def get_bgp_neighbors(self):
        instances = junos_views.junos_route_instance_table(self.device)
        uptime_table = junos_views.junos_bgp_uptime_table(self.device)
        bgp_neighbors = junos_views.junos_bgp_table(self.device)
        keys =['local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id']
        bgp_neighbor_data = {}
        for instance, instance_data in instances.get().items():
            if instance.startswith('__'):
                # junos internal instances
                continue
            instance_name = "global" if instance == 'master' else instance
            bgp_neighbor_data[instance_name] = {'peers': {}}
            for neighbor, data in bgp_neighbors.get(instance=instance).items():
                neighbor_data = {k: v for k, v in data}
                peer_ip = neighbor.split('+')[0]
                if 'router_id' not in bgp_neighbor_data[instance_name]:
                    # we only need to set this once
                    bgp_neighbor_data[instance_name]['router_id'] = unicode(neighbor_data['local_id'])
                peer = {key:self._parse_value(value) for key, value in neighbor_data.iteritems() if key in keys}
                peer['address_family'] = self._parse_route_stats(neighbor_data)
                bgp_neighbor_data[instance_name]['peers'][peer_ip] = peer
            for neighbor, uptime in uptime_table.get(instance=instance).items():
                bgp_neighbor_data[instance_name]['peers'][neighbor]['uptime'] = uptime[0][1]
        for key in bgp_neighbor_data.keys():
            if not bgp_neighbor_data[key]['peers']:
                del bgp_neighbor_data[key]
        return bgp_neighbor_data

    def get_lldp_neighbors(self):
        lldp = junos_views.junos_lldp_table(self.device)
        lldp.get()

        result = lldp.items()

        neighbors = dict()
        for neigh in result:
            if neigh[0] not in neighbors.keys():
                neighbors[neigh[0]] = list()
            neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]})

        return neighbors


    def get_lldp_neighbors_detail(self, interface=''):

        lldp_neighbors = dict()

        lldp_table = junos_views.junos_lldp_neighbors_detail_table(self.device)
        lldp_table.get()
        interfaces = lldp_table.get().keys()

        old_junos = self._convert(int, self.device.facts.get('version', '0.0').split('.')[0], '0') < 13

        lldp_table.GET_RPC = 'get-lldp-interface-neighbors'
        if old_junos:
            lldp_table.GET_RPC = 'get-lldp-interface-neighbors-information'

        for interface in interfaces:
            if old_junos:
                lldp_table.get(interface_name=interface)
            else:
                lldp_table.get(interface_device=interface)
            for item in lldp_table:
                if interface not in lldp_neighbors.keys():
                    lldp_neighbors[interface] = list()
                lldp_neighbors[interface].append({
                    'parent_interface'          : item.parent_interface,
                    'remote_port'               : item.remote_port,
                    'remote_chassis_id'         : item.remote_chassis_id,
                    'remote_port'               : item.remote_port,
                    'remote_port_description'   : item.remote_port_description,
                    'remote_system_name'        : item.remote_system_name,
                    'remote_system_description' : item.remote_system_description,
                    'remote_system_capab'       : item.remote_system_capab,
                    'remote_system_enable_capab': item.remote_system_enable_capab
                })

        return lldp_neighbors


    def cli(self, commands = None):

        cli_output = dict()

        if type(commands) is not list:
            raise TypeError('Please enter a valid list of commands!')

        for command in commands:
            try:
                cli_output[unicode(command)] = unicode(self.device.cli(command))
            except Exception as e:
                cli_output[unicode(command)] = 'Unable to execute command "{cmd}": {err}'.format(
                    cmd = command,
                    err = e
                )
                raise CommandErrorException(str(cli_output))

        return cli_output


    def get_bgp_config(self, group='', neighbor=''):

        def update_dict(d, u): # for deep dictionary update
            for k, v in u.iteritems():
                if isinstance(d, collections.Mapping):
                    if isinstance(v, collections.Mapping):
                        r = update_dict(d.get(k, {}), v)
                        d[k] = r
                    else:
                        d[k] = u[k]
                else:
                    d = {k: u[k]}
            return d

        def build_prefix_limit(**args):

            """
            This helper will transform the lements of a dictionary into nested dictionaries:
            Example:

                {
                    'inet_unicast_limit': 500,
                    'inet_unicast_teardown_threshold': 95,
                    'inet_unicast_teardown_timeout': 5
                }

                becomes:

                {
                    'inet': {
                        'unicast': {
                            'limit': 500,
                            'teardown': {
                                'threshold': 95,
                                'timeout': 5
                            }
                        }
                    }
                }

            """

            prefix_limit = dict()

            for key, value in args.iteritems():
                key_levels = key.split('_')
                length     = len(key_levels)-1
                temp_dict = {
                    key_levels[length]: value
                }
                for index in reversed(range(length)):
                    level = key_levels[index]
                    temp_dict = {level: temp_dict}
                update_dict(prefix_limit, temp_dict)

            return prefix_limit

        _COMMON_FIELDS_DATATYPE_ = {
            'description': unicode,
            'local_address': unicode,
            'local_as': int,
            'remote_as': int,
            'import_policy': unicode,
            'export_policy': unicode,
            'inet_unicast_limit_prefix_limit': int,
            'inet_unicast_teardown_threshold_prefix_limit': int,
            'inet_unicast_teardown_timeout_prefix_limit': int,
            'inet_unicast_novalidate_prefix_limit': int,
            'inet_flow_limit_prefix_limit': int,
            'inet_flow_teardown_threshold_prefix_limit': int,
            'inet_flow_teardown_timeout_prefix_limit': int,
            'inet_flow_novalidate_prefix_limit': unicode,
            'inet6_unicast_limit_prefix_limit': int,
            'inet6_unicast_teardown_threshold_prefix_limit': int,
            'inet6_unicast_teardown_timeout_prefix_limit': int,
            'inet6_unicast_novalidate_prefix_limit': int,
            'inet6_flow_limit_prefix_limit': int,
            'inet6_flow_teardown_threshold_prefix_limit': int,
            'inet6_flow_teardown_timeout_prefix_limit': int,
            'inet6_flow_novalidate_prefix_limit': unicode,
        }

        _PEER_FIELDS_DATATYPE_MAP_ = {
            'group': unicode,
            'authentication_key': unicode,
            'route_reflector_client': bool,
            'nhs': bool
        }
        _PEER_FIELDS_DATATYPE_MAP_.update(
            _COMMON_FIELDS_DATATYPE_
        )

        _GROUP_FIELDS_DATATYPE_MAP_ = {
            'type': unicode,
            'apply_groups': list,
            'remove_private_as': bool,
            'multipath': bool,
            'multihop_ttl': int
        }
        _GROUP_FIELDS_DATATYPE_MAP_.update(
            _COMMON_FIELDS_DATATYPE_
        )

        _DATATYPE_DEFAULT_ = {
            unicode: u'',
            int: 0,
            bool: False,
            list: []
        }

        bgp_config = dict()

        if group:
            bgp = junos_views.junos_bgp_config_group_table(self.device)
            bgp.get(group = group)
        else:
            bgp = junos_views.junos_bgp_config_table(self.device)
            bgp.get()
            neighbor = '' # if no group is set, no neighbor should be set either
        bgp_items = bgp.items()

        peers = junos_views.junos_bgp_config_peers_table(self.device)
        peers.get() # unfortunately cannot add filters for group name of neighbor address
        peers_items = peers.items()

        bgp_neighbors = dict()

        for bgp_group_neighbor in peers_items:
            bgp_peer_address = bgp_group_neighbor[0]
            if neighbor and bgp_peer_address != neighbor:
                continue  # if filters applied, jump over all other neighbors
            bgp_group_details = bgp_group_neighbor[1]
            bgp_peer_details = {
                field: _DATATYPE_DEFAULT_.get(datatype) \
                for field, datatype in _PEER_FIELDS_DATATYPE_MAP_.iteritems() \
                if '_prefix_limit' not in field
            }
            for elem in bgp_group_details:
                if not('_prefix_limit' not in elem[0] and elem[1] is not None):
                    continue
                datatype = _PEER_FIELDS_DATATYPE_MAP_.get(elem[0])
                default = _DATATYPE_DEFAULT_.get(datatype)
                key = elem[0]
                value = elem[1]
                if key in ['export_policy', 'import_policy']:
                    if isinstance(value, list):
                        value = ' '.join(value)
                bgp_peer_details.update({
                    key: self._convert(datatype, value, default)
                })
            prefix_limit_fields = dict()
            for elem in bgp_group_details:
                if '_prefix_limit' in elem[0] and elem[1] is not None:
                    datatype = _PEER_FIELDS_DATATYPE_MAP_.get(elem[0])
                    default = _DATATYPE_DEFAULT_.get(datatype)
                    prefix_limit_fields.update({
                        elem[0].replace('_prefix_limit', ''): self._convert(datatype, elem[1], default)
                    })
            bgp_peer_details['prefix_limit'] = build_prefix_limit(**prefix_limit_fields)
            # and all these things only because PyEZ cannto convert to a specifc datatype when retrieving config...
            group = bgp_peer_details.pop('group')
            if group not in bgp_neighbors.keys():
                bgp_neighbors[group] = dict()
            bgp_neighbors[group][bgp_peer_address] = bgp_peer_details
            if neighbor and bgp_peer_address == neighbor:
                break # found the desired neighbor

        for bgp_group in bgp_items:
            bgp_group_name = bgp_group[0]
            bgp_group_details = bgp_group[1]
            bgp_config[bgp_group_name] = {
                field: _DATATYPE_DEFAULT_.get(datatype) \
                for field, datatype in _GROUP_FIELDS_DATATYPE_MAP_.iteritems() \
                if '_prefix_limit' not in field
            }
            for elem in bgp_group_details:
                if not('_prefix_limit' not in elem[0] and elem[1] is not None):
                    continue
                datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(elem[0])
                default = _DATATYPE_DEFAULT_.get(datatype)
                key = elem[0]
                value = elem[1]
                if key in ['export_policy', 'import_policy']:
                    if isinstance(value, list):
                        value = ' '.join(value)
                bgp_config[bgp_group_name].update({
                    key: self._convert(datatype, value, default)
                })
            prefix_limit_fields = dict()
            for elem in bgp_group_details:
                if '_prefix_limit' in elem[0] and elem[1] is not None:
                    datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(elem[0])
                    default = _DATATYPE_DEFAULT_.get(datatype)
                    prefix_limit_fields.update({
                        elem[0].replace('_prefix_limit', ''): self._convert(datatype, elem[1], default)
                    })
            bgp_config[bgp_group_name]['prefix_limit'] = build_prefix_limit(**prefix_limit_fields)
            bgp_config[bgp_group_name]['neighbors'] = bgp_neighbors.get(bgp_group_name, {})

        return bgp_config

    def get_bgp_neighbors_detail(self, neighbor_address = ''):

        bgp_neighbors = dict()

        bgp_neighbors_table  = junos_views.junos_bgp_neighbors_table(self.device)

        bgp_neighbors_table.get(
            neighbor_address = neighbor_address
        )
        bgp_neighbors_items = bgp_neighbors_table.items()

        default_neighbor_details = {
            'up'                        : False,
            'local_as'                  : 0,
            'remote_as'                 : 0,
            'local_address'             : u'',
            'routing_table'             : u'',
            'local_address_configured'  : False,
            'local_port'                : 0,
            'remote_address'            : u'',
            'remote_port'               : 0,
            'multihop'                  : False,
            'multipath'                 : False,
            'remove_private_as'         : False,
            'import_policy'             : u'',
            'export_policy'             : u'',
            'input_messages'            : 0,
            'output_messages'           : 0,
            'input_updates'             : 0,
            'output_updates'            : 0,
            'messages_queued_out'       : 0,
            'connection_state'          : u'',
            'previous_connection_state' : u'',
            'last_event'                : u'',
            'suppress_4byte_as'         : False,
            'local_as_prepend'          : False,
            'holdtime'                  : 0,
            'configured_holdtime'       : 0,
            'keepalive'                 : 0,
            'configured_keepalive'      : 0,
            'active_prefix_count'       : 0,
            'received_prefix_count'     : 0,
            'accepted_prefix_count'     : 0,
            'suppressed_prefix_count'   : 0,
            'advertise_prefix_count'    : 0,
            'flap_count'                : 0
        }

        _OPTION_KEY_MAP_ = {
            'RemovePrivateAS': 'remove_private_as',
            'Multipath'      : 'multipath',
            'Multihop'       : 'multihop',
            'AddressFamily'  : 'local_address_configured'
            # 'AuthKey'        : 'authentication_key_set'
            # but other vendors do not specify if auth key is set
            # other options:
            # Preference, HoldTime, Ttl, LogUpDown, Refresh
        }

        for bgp_neighbor in bgp_neighbors_items:
            remote_as = int(bgp_neighbor[0])
            if remote_as not in bgp_neighbors.keys():
                bgp_neighbors[remote_as] = list()
            neighbor_details = default_neighbor_details.copy()
            neighbor_details.update(
                {elem[0]: elem[1] for elem in bgp_neighbor[1] if elem[1] is not None}
            )
            options = neighbor_details.pop('options', '')
            if isinstance(options, str):
                options_list = options.split()
                for option in options_list:
                    key = _OPTION_KEY_MAP_.get(option)
                    if key is None:
                        continue
                    neighbor_details[key] = True
            four_byte_as = neighbor_details.pop('4byte_as', 0)
            local_address = neighbor_details.pop('local_address', '')
            local_details = local_address.split('+')
            neighbor_details['local_address'] = unicode(local_details[0])
            if len(local_details) == 2:
                neighbor_details['local_port']= int(local_details[1])
            else:
                neighbor_details['local_port']=179
            neighbor_details['suppress_4byte_as'] = (remote_as != four_byte_as)
            peer_address = neighbor_details.pop('peer_address', '')
            remote_details = peer_address.split('+')
            neighbor_details['remote_address'] = unicode(remote_details[0])
            if len(remote_details) == 2:
                neighbor_details['remote_port']    = int(remote_details[1])
            else:
                neighbor_details['remote_port'] = 179
            bgp_neighbors[remote_as].append(neighbor_details)

        return bgp_neighbors


    def get_arp_table(self):

        # could use ArpTable
        # from jnpr.junos.op.phyport import ArpTable
        # and simply use it
        # but
        # we need:
        #   - filters
        #   - group by VLAN ID
        #   - hostname & TTE fields as well

        arp_table = list()

        arp_table_raw = junos_views.junos_arp_table(self.device)
        arp_table_raw.get()
        arp_table_items = arp_table_raw.items()

        for arp_table_entry in arp_table_items:
            arp_entry = {
                elem[0]: elem[1] for elem in arp_table_entry[1]
            }
            tte = arp_entry.pop('tte')
            arp_entry['age'] = tte
            # must compute age based on TTE
            arp_table.append(arp_entry)

        return arp_table

    def get_ntp_peers(self):

        ntp_table = junos_views.junos_ntp_peers_config_table(self.device)
        ntp_table.get()

        ntp_peers = ntp_table.items()

        if not ntp_peers:
            return {}

        return {unicode(peer[0]):{} for peer in ntp_peers}

    def get_ntp_stats(self):

        # NTP Peers does not have XML RPC defined
        # thus we need to retrieve raw text and parse...
        # :(

        ntp_stats = list()

        REGEX = (
            '^\s?(\+|\*|x|-)?([a-zA-Z0-9\.+-:]+)'
            '\s+([a-zA-Z0-9\.]+)\s+([0-9]{1,2})'
            '\s+(-|u)\s+([0-9h-]+)\s+([0-9]+)'
            '\s+([0-9]+)\s+([0-9\.]+)\s+([0-9\.-]+)'
            '\s+([0-9\.]+)\s?$'
        )

        ntp_assoc_output = self.device.cli('show ntp associations no-resolve')
        ntp_assoc_output_lines = ntp_assoc_output.splitlines()

        for ntp_assoc_output_line in ntp_assoc_output_lines[3:]: #except last line
            line_search = re.search(REGEX, ntp_assoc_output_line, re.I)
            if not line_search:
                continue # pattern not found
            line_groups = line_search.groups()
            try:
                ntp_stats.append({
                    'remote'        : unicode(line_groups[1]),
                    'synchronized'  : (line_groups[0] == '*'),
                    'referenceid'   : unicode(line_groups[2]),
                    'stratum'       : int(line_groups[3]),
                    'type'          : unicode(line_groups[4]),
                    'when'          : unicode(line_groups[5]),
                    'hostpoll'      : int(line_groups[6]),
                    'reachability'  : int(line_groups[7]),
                    'delay'         : float(line_groups[8]),
                    'offset'        : float(line_groups[9]),
                    'jitter'        : float(line_groups[10])
                })
            except Exception:
                continue # jump to next line

        return ntp_stats

    def get_interfaces_ip(self):

        interfaces_ip = dict()

        interface_table = junos_views.junos_ip_interfaces_table(self.device)
        interface_table.get()
        interface_table_items = interface_table.items()

        _FAMILY_VMAP_ = {
            'inet'  : u'ipv4',
            'inet6' : u'ipv6'
            # can add more mappings
        }

        for interface_details in interface_table_items:
            try:
                ip_address = interface_details[0]
                address    = unicode(ip_address.split('/')[0])
                prefix     = self._convert(int, ip_address.split('/')[-1], 0)
                interface  = unicode(interface_details[1][0][1])
                family_raw = interface_details[1][1][1]
                family     = _FAMILY_VMAP_.get(family_raw)
                if not family:
                    continue
                if interface not in interfaces_ip.keys():
                    interfaces_ip[interface] = dict()
                if family not in interfaces_ip[interface].keys():
                    interfaces_ip[interface][family] = dict()
                if address not in interfaces_ip[interface][family].keys():
                    interfaces_ip[interface][family][address] = dict()
                interfaces_ip[interface][family][address][u'prefix_length'] = prefix
            except Exception:
                continue

        return interfaces_ip

    def get_mac_address_table(self):

        mac_address_table = list()

        mac_table = junos_views.junos_mac_address_table(self.device)
        mac_table.get()
        mac_table_items = mac_table.items()

        default_values = {
            'mac'       : u'',
            'interface' : u'',
            'vlan'      : 0,
            'static'    : False,
            'active'    : True,
            'moves'     : 0,
            'last_move' : 0.0
        }

        for mac_table_entry in mac_table_items:
            mac_entry = default_values.copy()
            mac_entry.update(
                {elem[0]: elem[1] for elem in mac_table_entry[1]}
            )
            mac_address_table.append(mac_entry)

        return mac_address_table

    def get_route_to(self, destination = '', protocol = ''):

        routes = {}

        if not isinstance(destination, str):
            raise TypeError('Please specify a valid destination!')

        if not isinstance(protocol, str) or protocol.lower() not in ['static', 'bgp', 'isis']:
            raise TypeError("Protocol not supported: {protocol}.".format(
                protocol = protocol
            ))

        protocol = protocol.lower()

        _COMMON_PROTOCOL_FIELDS_ = [
            'destination',
            'prefix_length',
            'protocol',
            'current_active',
            'last_active',
            'age',
            'next_hop',
            'outgoing_interface',
            'selected_next_hop',
            'preference',
            'inactive_reason',
            'routing_table'
        ] # identifies the list of fileds common for all protocols

        _BOOLEAN_FIELDS_ = [
            'current_active',
            'selected_next_hop',
            'last_active'
        ] # fields expected to have boolean values

        _PROTOCOL_SPECIFIC_FIELDS_ = {
            'bgp': [
                'local_as',
                'remote_as',
                'as_path',
                'communities',
                'local_preference',
                'preference2',
                'remote_address',
                'metric',
                'metric2'
            ],
            'isis': [
                'level',
                'metric',
                'local_as'
            ]
        }

        routes_table = junos_views.junos_protocol_route_table(self.device)

        try:
            routes_table.get(
                destination=destination,
                protocol=protocol
            )
        except RpcTimeoutError:
            # on devices with milions of routes
            # in case the destination is too generic (e.g.: 10/8)
            # will take very very long to determine all routes and
            # moreover will return a huge list
            raise CommandTimeoutException('Too many routes returned! Please try with a longer prefix!')
        except Exception as e:
            raise CommandErrorException('Cannot retrieve routes! Reason: {err}'.format(err = e))

        routes_items = routes_table.items()

        for route in routes_items:
            d = dict()
            next_hop = route[0]
            d = {elem[0]: elem[1] for elem in route[1]}
            destination = d.pop('destination', '')
            prefix_length = d.pop('prefix_length', 32)
            destination = '{d}/{p}'.format(
                d=destination,
                p=prefix_length
            )
            d.update({key: False for key in _BOOLEAN_FIELDS_ if d.get(key) is None})
            as_path = d.get('as_path')
            if as_path is not None:
                d['as_path'] = as_path.split(' I ')[0].replace('AS path:', '').replace('I', '').strip()
                # to be sure that contains only AS Numbers
            if d.get('inactive_reason') is None:
                d['inactive_reason'] = u''
            communities = d.get('communities')
            if communities is not None and type(communities) is not list:
                d['communities'] = [communities]
            d['next_hop'] = unicode(next_hop)
            d_keys = d.keys()
            # fields that are not in _COMMON_PROTOCOL_FIELDS_ are supposed to be protocol specific
            all_protocol_attributes = {key: d.pop(key) for key in d_keys if key not in _COMMON_PROTOCOL_FIELDS_}
            protocol_attributes = {
                key: value for key, value in all_protocol_attributes.iteritems() \
                if key in _PROTOCOL_SPECIFIC_FIELDS_.get(protocol)
            }
            d['protocol_attributes'] = protocol_attributes
            if destination not in routes.keys():
                routes[destination] = list()
            routes[destination].append(d)

        return routes

    def get_snmp_information(self):

        snmp_information = dict()

        _AUTHORIZATION_MODE_MAP_ = {
            'read-only': u'ro',
            'read-write': u'rw'
        }

        snmp_config = junos_views.junos_snmp_config_table(self.device)
        snmp_config.get()
        snmp_items = snmp_config.items()

        if not snmp_items:
            return snmp_information

        communities = list()
        for snmp_config_out in snmp_items:
            community_name = snmp_config_out[0]
            community_details = snmp_config_out[1]
            communities.append({
                c[0]: c[1] for c in community_details
            })

        snmp_information = {
            'contact': self._convert(unicode, communities[0].get('contact')),
            'location': self._convert(unicode, communities[0].get('location')),
            'chassis_id': self._convert(unicode, communities[0].get('chassis')),
            'community': {}
        }

        for snmp_entry in communities:
            name = self._convert(unicode, snmp_entry.get('name'))
            authorization = self._convert(unicode, snmp_entry.get('authorization'))
            snmp_information['community'][name] = {
                'mode': _AUTHORIZATION_MODE_MAP_.get(authorization, u''),
                'acl': u''
            }

        return snmp_information


    def get_probes_config(self):

        probes = dict()

        probes_table = junos_views.junos_rpm_probes_config_table(self.device)
        probes_table.get()
        probes_table_items = probes_table.items()

        for probe_test in probes_table_items:
            test_name = unicode(probe_test[0])
            test_details = {
                p[0]: p[1] for p in probe_test[1]
            }
            probe_name = self._convert(unicode, test_details.pop('probe_name'))
            target = self._convert(unicode, test_details.pop('target', ''))
            test_interval = self._convert(int, test_details.pop('test_interval', '0'))
            probe_count = self._convert(int, test_details.pop('probe_count', '0'))
            probe_type = self._convert(unicode, test_details.pop('probe_type', ''))
            source = self._convert(unicode, test_details.pop('source_address', ''))
            if probe_name not in probes.keys():
                probes[probe_name] = dict()
            probes[probe_name][test_name] = {
                'probe_type'    : probe_type,
                'target'        : target,
                'source'        : source,
                'probe_count'   : probe_count,
                'test_interval' : test_interval
            }

        return probes


    def get_probes_results(self):

        probes_results = dict()

        probes_results_table = junos_views.junos_rpm_probes_results_table(self.device)
        probes_results_table.get()
        probes_results_items = probes_results_table.items()

        for probe_result in probes_results_items:
            probe_name = unicode(probe_result[0])
            test_results = {
                p[0]: p[1] for p in probe_result[1]
            }
            for test_param_name, test_param_value in test_results.iteritems():
                if isinstance(test_param_value, float):
                    test_results[test_param_name] = test_param_value * 1e-3 # convert from useconds to mseconds
            test_name = test_results.pop('test_name', '')
            source = test_results.get('source', u'')
            if source is None:
                test_results['source'] = u''
            if probe_name not in probes_results.keys():
                probes_results[probe_name] = dict()
            probes_results[probe_name][test_name] = test_results

        return probes_results

    def traceroute(self, destination, source='', ttl=0, timeout=0):

        traceroute_result = dict()

        # calling form RPC does not work properly :(
        # but defined junos_route_instance_table just in case

        source_str = ''
        maxttl_str = ''
        wait_str = ''

        if source:
            source_str = 'source {source}'.format(source=source)
        if ttl:
            maxttl_str = 'ttl {ttl}'.format(ttl=ttl)
        if timeout:
            wait_str = 'wait {timeout}'.format(timeout=timeout)

        traceroute_command = 'traceroute {destination} {source} {maxttl} {wait}'.format(
            destination=destination,
            source=source_str,
            maxttl=maxttl_str,
            wait=wait_str
        )

        traceroute_rpc = E('command', traceroute_command)
        rpc_reply = self.device._conn.rpc(traceroute_rpc)._NCElement__doc # make direct RPC call via NETCONF
        traceroute_results = rpc_reply.find('.//traceroute-results')

        traceroute_success = traceroute_results.find('traceroute-success')
        traceroute_failure = self._find_txt(traceroute_results, 'traceroute-failure', '')
        error_message = self._find_txt(traceroute_results, 'rpc-error/error-message', '')

        error = ''

        if traceroute_failure and error_message:
            return {'error': '{}: {}'.format(traceroute_failure, error_message)}

        traceroute_result['success'] = dict()
        for hop in traceroute_results.findall('hop'):
            ttl_value = self._convert(int, self._find_txt(hop, 'ttl-value'), 1)
            if ttl_value not in traceroute_result['success']:
                traceroute_result['success'][ttl_value] = {'probes': {}}
            for probe in hop.findall('probe-result'):
                probe_index = self._convert(int, self._find_txt(probe, 'probe-index'), 0)
                ip_address = unicode(self._find_txt(probe, 'ip-address', u'*'))
                host_name = unicode(self._find_txt(probe, 'host-name', u'*'))
                rtt = self._convert(float, self._find_txt(probe, 'rtt'), 0) * 1e-3 # ms
                traceroute_result['success'][ttl_value]['probes'][probe_index] = {
                    'ip_address': ip_address,
                    'host_name': host_name,
                    'rtt': rtt
                }

        return traceroute_result

    def get_users(self):

        users = dict()

        _JUNOS_CLASS_CISCO_PRIVILEGE_LEVEL_MAP = {
            'super-user': 15,
            'superuser': 15,
            'operator': 5,
            'read-only': 1,
            'unauthorized': 0
        }

        _DEFAULT_USER_DETAILS = {
            'level': 0,
            'password': '',
            'sshkeys': []
        }

        users_table = junos_views.junos_users_table(self.device)
        users_table.get()
        users_items = users_table.items()

        for user_entry in users_items:
            username = user_entry[0]
            user_details = _DEFAULT_USER_DETAILS.copy()
            user_details.update({
                d[0]: d[1] for d in user_entry[1] if d[1]
            })
            user_class = user_details.pop('class', '')
            level = _JUNOS_CLASS_CISCO_PRIVILEGE_LEVEL_MAP.get(user_class, 0)
            user_details.update({
                'level': level
            })
            user_details['sshkeys'] = [
                user_details.pop(key) for key in ['ssh_rsa', 'ssh_dsa', 'ssh_ecdsa'] if user_details.get(key, '')
            ]
            users[username] = user_details

        return users
Ejemplo n.º 35
0
class EzncDriver(ngage.plugins.DriverPlugin):
    """
    driver for junos-eznc
        pip install junos-eznc
    """
    plugin_type = 'eznc'

    def _do_init(self):
        config = self.config

        self.host = config.get('host')
        self.port = config.get('port', 22)
        if not self.port:
            self.port = 22
        self.user = config.get('user')
        self.password = config.get('password')
        self.dev = Device(self.host,
                          port=self.port,
                          user=self.user,
                          password=self.password)

    def _do_open(self):
        try:
            self.dev.open()
            self.dev.bind(cu=Config)

        except ConnectAuthError:
            raise AuthenticationError

    def _do_close(self):
        self.dev.close()

    def _do_pull(self):
        options = {'format': 'text'}

        config = self.dev.rpc.get_config(filter_xml=None, options=options)
        config = config.text.encode('ascii', 'replace')
        return config

    def _do_push(self, fname, **kwargs):
        try:
            self.dev.cu.load(path=fname, format='text')

        # bogus exception on warnings
        except ConfigLoadError as e:
            errs = []
            for err in e.errs:
                # skip warnings
                if not err['severity'] or err['severity'] == 'warning':
                    continue
                # expand multiple errors split by newlines
                errs = errs + e.message.split('\n')

            if errs:
                if len(errs) == 1:
                    raise ConfigError(errs[0])
                else:
                    raise ConfigError(errs)

    def _do_diff(self, index=0):
        return self.dev.cu.diff(index)

    def _do_lock(self):
        self.dev.cu.lock()

    def _do_unlock(self):
        self.dev.cu.unlock()

    def _do_commit(self, **kwargs):
        self.dev.cu.commit()

    def _do_check(self):
        self.dev.cu.commit_check()

    def _do_rollback(self, index=0):
        self.dev.cu.rollback(index)
Ejemplo n.º 36
0
def main():
    hosts = config.get('hosts')

    for host in hosts:
        dev = Device(host=host, user=user, password=password)
        # Open the connection & config
        try:
            print("Opening connnection to: {}".format(host))
            dev.open()
        except Exception as err:
            print("Cannot connect to device: {}".format(err))
            return
        dev.bind(cu=Config)
        # Lock the configuration, load changes, commit
        print("Locking the configuration on: {}".format(host))
        try:
            dev.cu.lock()
        except LockError:
            print("Error: Unable to lock configuration on: {}".format(host))
            dev.close()
            return
        print("Loading configuration changes on: {}".format(host))
        try:
            set_commands = """
            delete policy-options prefix-list edge-block
            delete policy-options prefix-list edge-block-exceptions
            """
            dev.cu.load(set_commands, format='set')
            dev.cu.load(template_path=template,
                        template_vars=config, format='text')
        except ValueError as err:
            print(err.message)
        except Exception as err:
            if err.rsp.find('.//ok') is None:
                rpc_msg = err.rsp.findtext('.//error-message')
                print("Unable to load config changes: {}".format(rpc_msg))
            print("Unlocking the configuration on: {}".format(host))
            try:
                dev.cu.unlock()
            except UnlockError:
                print("Error: Unable to unlock config on: {}".format(host))
            dev.close()
            return
        print("Committing the configuration on: {}".format(host))
        try:
            dev.cu.commit()
            # print(dev.cu.diff())
        except CommitError:
            print("Error: Unable to commit configuration on: {}".format(host))
            print("Unlocking the configuration on: {}".format(host))
            try:
                dev.cu.unlock()
            except UnlockError:
                print("Error: Unable to unlock config on: {}".format(host))
            dev.close()
            return
        print "Unlocking the configuration on:", host
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Error: Unable to unlock config on: {}".format(host))
        print("Closing connection to: {}".format(host))
        dev.close()
Ejemplo n.º 37
0
    'ge-0/0/1': '72.114.255.3/19',
    'ge-0/0/2': '72.114.255.34/19',
    'ge-0/0/3': '72.114.196.0/19'
}
if_config_check = {'ge-0/0/1': '', 'ge-0/0/2': 'passive', 'ge-0/0/3': ''}
if_area = {
    'ge-0/0/1': 'area 0.0.0.20',
    'ge-0/0/2': 'area 0.0.0.20',
    'ge-0/0/3': 'area 0.0.0.20'
}
var_dict = {
    'if_config': if_config,
    'if_config_check': if_config_check,
    'if_area': if_area
}

try:
    device.open()
    device.bind(conf=Config)
    device.conf.load(template_path='template_ospf.conf',
                     template_vars=var_dict,
                     merge=True)
    success = device.conf.commit()
    print("Success : {}".format(success))

except (RpcError, ConnectError) as err:
    print("\nError: " + repr(err))

finally:
    device.close()
Ejemplo n.º 38
0
class TestScp(unittest.TestCase):

    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    def test_scp_console(self):
        dev = Device(host='1.1.1.1', mode='telnet')
        self.assertRaises(RuntimeError, SCP, dev)

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, mock_proxy, mock_paramiko, mock_connect,
                              open_mock, os_mock):
        os_mock.path.exists.return_value = True
        # self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_once()

    def test_scp_progress(self):
        scp = SCP(self.dev)
        print (scp._scp_progress('test', 100, 50))

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_user_def_progress(self, mock_scpclient, mock_put, mock_ssh):
        mock_scpclient.return_value = None

        def fn(file, total, tfd):
            pass
        package = 'test.tgz'
        with SCP(self.dev, progress=fn) as scp:
            scp.put(package)
        self.assertEqual(
            mock_scpclient.mock_calls[0][2]['progress'].__name__, 'fn')

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_user_def_progress_args_2(self, mock_scpclient, mock_put,
                                          mock_ssh):
        mock_scpclient.return_value = None

        def myprogress(dev, report):
            print ("host: %s, report: %s" % (dev.hostname, report))
        package = 'test.tgz'
        with SCP(self.dev, progress=myprogress) as scp:
            scp.put(package)
        self.assertEqual(
            mock_scpclient.mock_calls[0][2]['progress'].__name__,
            '_scp_progress')

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_progress_true(self, mock_scpclient, mock_put, mock_sshclient):
        mock_scpclient.return_value = None
        package = 'test.tgz'
        with SCP(self.dev, progress=True) as scp:
            scp.put(package)
        self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__,
                         '_scp_progress')

    @patch('ncclient.manager.connect')
    @patch('paramiko.SSHClient.connect')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_ssh_private_key_file(self, mock_scpclient, mock_put,
                                  mock_sshclient, mock_ncclient):
        mock_scpclient.return_value = None
        package = 'test.tgz'
        dev = Device(host='1.1.1.1', user='******',
                     ssh_private_key_file='/Users/test/testkey')
        dev.open(gather_facts=False)
        with SCP(dev) as scp:
            scp.put(package)
        self.assertEqual(mock_sshclient.mock_calls[0][2]['key_filename'],
                         '/Users/test/testkey')

    @contextmanager
    def capture(self, command, *args, **kwargs):
        out, sys.stdout = sys.stdout, StringIO()
        command(*args, **kwargs)
        sys.stdout.seek(0)
        yield sys.stdout.read()
        sys.stdout = out
Ejemplo n.º 39
0
import sys
import os
from pprint import pprint
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
import jnpr


device = Device(host='10.247.140.4', user='******', password='******' )
device.open()

#pprint( device.facts )
device.bind(cfg=Config)
try:
    device.rpc.open_configuration(private=True)
except jnpr.junos.exception.RpcError as e:
    if 'severity: warning' in str(e):
        print str(e) 
        pass
    else:
        raise

for line in open("fila"):
 elhay = Config(device)
 set_cmd = line
 elhay.load(set_cmd, format='set')
 elhay.pdiff()
 elhay.commit()

#for line in open("fila"):
# print device.cli(line)
Ejemplo n.º 40
0
def load_with_pyez(merge_opt, overwrite_opt, format_opt, conf_file, log_file,
                   ip, hostname, username, password):
    """ Purpose: Perform the actual loading of the config file. Catch any errors.
        Parameters:
            format_opt      -   defines the format of input "set" or "hierarchical"
            merge_opt       -   the merge options selection, "loadmerge"
            overwrite_opt   -   the overwrite option selection, "loadoverwrite"
            conf_file       -   the configuration file name, including path and filename
            log_file        -   the log file name, including path and filename
            ip              -   ip address of device
            hostname        -   device hostname
            username        -   username for logging in
            password        -   password for username
    """
    dot = "."
    screen_and_log(
        ("Applying configuration on {0} ({1}) ".format(hostname, ip)),
        log_file)
    screen_and_log(dot, log_file)
    dev = Device(ip, user=username, password=password)
    try:
        dev.open()
    except ConnectError as err:
        screen_and_log(("{0}: Cannot connect to device : {1}".format(ip, err)),
                       log_file)
        return
    dev.bind(cu=Config)

    #print("Try locking the configuration...")
    screen_and_log(dot, log_file)
    try:
        dev.cu.lock()
    except LockError as err:
        screen_and_log(
            ("{0}: Unable to lock configuration : {1}".format(ip, err)),
            log_file)
        dev.close()
        return

    #print("Try loading configuration changes...")
    screen_and_log(dot, log_file)
    try:
        if format is None:
            dev.cu.load(path=conf_file,
                        merge=merge_opt,
                        overwrite=overwrite_opt)
        else:
            dev.cu.load(path=conf_file, merge=merge_opt, format="set")
    except (ConfigLoadError, Exception) as err:
        if err.rpc_error['severity'] == 'warning':
            pass
        elif 'statement not found' in err.message:
            pass
        else:
            screen_and_log(
                ("{0}: Unable to load configuration changes : {1}".format(
                    ip, err)), log_file)
            screen_and_log(("{0}: Unlocking the configuration".format(ip)),
                           log_file)
            try:
                dev.cu.unlock()
            except UnlockError as err:
                screen_and_log(
                    ("{0}: Unable to unlock configuration : {1}".format(
                        ip, err)), log_file)
            dev.close()
            return

    #print("Try committing the configuration...")
    screen_and_log(dot, log_file)
    try:
        dev.cu.commit()
    except CommitError as err:
        screen_and_log(
            ("{0}: Unable to commit configuration : {1}".format(ip, err)),
            log_file)
        screen_and_log(("{0}: Unlocking the configuration".format(ip)),
                       log_file)
        try:
            dev.cu.unlock()
        except UnlockError as err:
            screen_and_log(
                ("{0}: Unable to unlock configuration : {1}".format(ip, err)),
                log_file)
        dev.close()
        return

    #print("Try Unlocking the configuration...")
    screen_and_log(dot, log_file)
    try:
        dev.cu.unlock()
    except UnlockError as err:
        screen_and_log(
            ("{0}: Unable to unlock configuration : {1}".format(ip, err)),
            log_file)
        dev.close()
        return

    # End the NETCONF session and close the connection
    dev.close()
    screen_and_log((" Completed!\n"), log_file)
Ejemplo n.º 41
0
class JunOSDriver(NetworkDriver):

    def __init__(self, hostname, username, password, timeout=60):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.timeout = timeout
        self.device = Device(hostname, user=username, password=password)
        self.config_replace = False

    def open(self):
        self.device.open()
        self.device.timeout = self.timeout
        self.device.bind(cu=Config)
        self.device.cu.lock()

    def close(self):
        self.device.cu.unlock()
        self.device.close()

    def _load_candidate(self, filename, config, overwrite):
        if filename is None:
            configuration = config
        else:
            with open(filename) as f:
                configuration = f.read()

        try:
            self.device.cu.load(configuration, format='text', overwrite=overwrite)
        except ConfigLoadError as e:
            if self.config_replace:
                raise ReplaceConfigException(e.message)
            else:
                raise MergeConfigException(e.message)

    def load_replace_candidate(self, filename=None, config=None):
        self.config_replace = True
        self._load_candidate(filename, config, True)

    def load_merge_candidate(self, filename=None, config=None):
        self.config_replace = False
        self._load_candidate(filename, config, False)

    def compare_config(self):
        diff = self.device.cu.diff()

        if diff is None:
            return ''
        else:
            return diff.strip()

    def commit_config(self):
        self.device.cu.commit()

    def discard_config(self):
        self.device.cu.rollback(rb_id=0)

    def rollback(self):
        self.device.cu.rollback(rb_id=1)
        self.commit_config()

    def get_facts(self):

        output = self.device.facts

        uptime = 0
        if 'RE0' in output:
            uptime = output['RE0']['up_time']

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()
        interface_list = interfaces.keys()

        return {
            'vendor': u'Juniper',
            'model': unicode(output['model']),
            'serial_number': unicode(output['serialnumber']),
            'os_version': unicode(output['version']),
            'hostname': unicode(output['hostname']),
            'fqdn': unicode(output['fqdn']),
            'uptime': string_parsers.convert_uptime_string_seconds(uptime),
            'interface_list': interface_list
        }

    def get_interfaces(self):

        # init result dict
        result = {}

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()

        # convert all the tuples to our pre-defined dict structure
        for iface in interfaces.keys():
            result[iface] = {
                'is_up': interfaces[iface]['is_up'],
                'is_enabled': interfaces[iface]['is_enabled'],
                'description': interfaces[iface]['description'] or u'',
                'last_flapped': interfaces[iface]['last_flapped'] or -1,
                'mac_address': unicode(interfaces[iface]['mac_address'])
            }
            result[iface]['last_flapped'] = float(result[iface]['last_flapped'])

            match = re.search(r'\d+', interfaces[iface]['speed'] or '')
            if match is not None:
                result[iface]['speed'] = int(match.group(0))
            else:
                result[iface]['speed'] = -1

        return result

    def get_interfaces_counters(self):
        query = junos_views.junos_iface_counter_table(self.device)
        query.get()
        interface_counters = dict()
        for interface, counters in query.items():
            interface_counters[interface] = {k: v or -1 for k, v in counters}
        return interface_counters

    @staticmethod
    def _get_address_family(table):
        """
        Function to derive address family from a junos table name
        :params table: The name of the routing table
        :returns: address family
        """
        address_family_mapping = {
            'inet': 'ipv4',
            'inet6': 'ipv6'
        }
        family = table.split('.')[-2]
        return address_family_mapping[family]

    def get_bgp_neighbors(self):
        # Setup the views
        instances = junos_views.junos_route_instance_table(self.device)
        uptime_table = junos_views.junos_bgp_uptime_table(self.device)
        bgp_neigbors = junos_views.junos_bgp_table(self.device)
        # prepare data
        bgp_neigbor_data = dict()
        for instance, instance_data in instances.get().items():
            if instance.startswith('__'):
                # junos internal instances
                continue

            instance_name = "global" if instance == 'master' else instance

            bgp_neigbor_data[instance_name] = dict(peers=dict())
            for neighbor, neighbor_data in bgp_neigbors.get(instance=instance).items():
                structured_neighbor_data = {k: v for k, v in neighbor_data}
                peer = neighbor.split('+')[0]
                bgp_neigbor_data[instance_name]['peers'][peer] = dict()
                for key in ['local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id']:
                    bgp_neigbor_data[instance_name]['peers'][peer][key] = structured_neighbor_data[key] or u''
                if 'router_id' not in bgp_neigbor_data[instance_name].keys():
                    # we only need to set this once
                    bgp_neigbor_data[instance_name]['router_id'] = structured_neighbor_data['local_id']
                if structured_neighbor_data['is_up'] is False:
                    # if the session is down there is no table data to parse
                    continue
                elif isinstance(structured_neighbor_data['tables'], list):
                    for idx, table in enumerate(structured_neighbor_data['tables']):
                        family = self._get_address_family(table)
                        bgp_neigbor_data[instance_name]['peers'][peer][family] = dict()
                        for metric in ['received_prefixes', 'accepted_prefixes', 'sent_prefixes']:
                            bgp_neigbor_data[instance_name]['peers'][peer][family][metric] = structured_neighbor_data[metric][idx]
                else:
                    family = self._get_address_family(structured_neighbor_data['tables'])
                    bgp_neigbor_data[instance_name]['peers'][peer][family] = dict()
                    bgp_neigbor_data[instance_name]['peers'][peer][family]['received_prefixes'] = structured_neighbor_data['received_prefixes']
                    bgp_neigbor_data[instance_name]['peers'][peer][family]['accepted_prefixes'] = structured_neighbor_data['accepted_prefixes']
                    bgp_neigbor_data[instance_name]['peers'][peer][family]['sent_prefixes'] = structured_neighbor_data['sent_prefixes']
            for neighbor, uptime in uptime_table.get(instance=instance).items():
                bgp_neigbor_data[instance_name]['peers'][neighbor]['uptime'] = uptime[0][1]
        return bgp_neigbor_data

    def get_lldp_neighbors(self):
        lldp = junos_views.junos_lldp_table(self.device)
        lldp.get()

        result = lldp.items()

        neighbors = dict()
        for neigh in result:
            if neigh[0] not in neighbors.keys():
                neighbors[neigh[0]] = list()
            neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]})

        return neighbors
Ejemplo n.º 42
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    def test_new_console_return(self):
        dev = Device(host='1.1.1.1', user='******', password='******',
                     port=23, gather_facts=False)
        self.assertTrue(isinstance(dev, Console))

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)
        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch(builtin_string + '.open', mock):
            if sys.version > '3':
                builtin_file = 'io.TextIOWrapper'
            else:
                builtin_file = builtin_string + '.file'
            with patch(builtin_file, MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_master_is_master(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_backup(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = False
        localdev.facts._cache['RE_hw_mi'] = False
        localdev.facts._cache['current_re'] = ['re0']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_multi_chassis_non_master1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_multi_chassis_non_master2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re0', 'member1-re0',
                                               'lcc1-master', 'member1-master',
                                               'member1']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.master, None)

    def test_device_master_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['foo', 'bar']
        self.assertEqual(localdev.master, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_master_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.master, None)

    def test_device_master_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.master = 'foo'

    def test_device_re_name_is_re0(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'tapir',
                                                  're1': 'tapir1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_lcc_re1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 'lcc1-re1')

    def test_device_re_name_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['foo']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        localdev.facts._cache['hostname_info'] = None
        self.assertEqual(localdev.re_name, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_re_name_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.re_name = 'foo'

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, 'localhost')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = '/home/rsherman/.ssh/config'
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(
                host='2.2.2.2',
                user='******',
                password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            self.dev.facts._cache['current_re'] = ['re0']
            assert self.dev.facts['version'] == facts['version']

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.factcache.warnings')
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.dev.facts_refresh(warnings_on_failure=True)
            self.assertTrue(mock_warnings.warn.called)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_facts_error_exception_on_error(self, mock_warnings,
                                                   mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_old_style_facts_error_exception_on_error(self,
                                                             mock_warnings,
                                                             mock_execute):
        self.dev._fact_style = 'old'
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    def test_device_facts_refresh_unknown_fact_style(self):
        self.dev._fact_style = 'bad'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh()

    def test_device_facts_refresh_old_fact_style_with_keys(self):
        self.dev._fact_style = 'old'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh(keys='domain')

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'test')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._auth_password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host='2.2.2.2', user='******', password='******')
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    def test_device_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            ofacts = self.dev.ofacts

    def test_device_set_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            self.dev.ofacts = False

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory',
                                      warning=False).tag, 'cli')

    @patch('jnpr.junos.device.json.loads')
    def test_device_rpc_json_ex(self, mock_json_loads):
        self.dev.facts = facts
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        ex = ValueError('Extra data ')
        ex.message = 'Extra data '  # for py3 as we dont have message thr
        mock_json_loads.side_effect = [
            ex,
            self._mock_manager(etree.fromstring(
                '<get-route-information format="json"/>'))]
        self.dev.rpc.get_route_information({'format': 'json'})
        self.assertEqual(mock_json_loads.call_count, 2)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('show system uptime')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show system uptime | match foo | count')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_complex(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show interfaces ge-0/0/0.0 routing-instance all media')
        self.assertEqual("rpc.get_interface_information("
                         "routing_instance='all', media=True, "
                         "interface_name='ge-0/0/0.0')", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_invalid(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('foo')
        self.assertEqual(None, data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_format_json(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interface terse',
                            warning=False, format='json')
        self.assertEqual(type(data), dict)
        self.assertEqual(data['interface-information'][0]
                         ['physical-interface'][0]['oper-status'][0]['data'],
                         'up')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration',
                                                   warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms',
                                                warning=False))

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_cli_output_warning(self, mock_warnings, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interfaces ge-0/0/0.0 routing-instance '
                            'all media', format='xml')
        ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/'
                           'address-family[address-family-name="inet"]/'
                           'interface-address/ifa-local')
        self.assertTrue('192.168.100.1' in ip)
        self.assertTrue(mock_warnings.warn.called)
        rpc_string = "rpc.get_interface_information(routing_instance='all', "\
                     "media=True, interface_name='ge-0/0/0.0')"
        self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0])

    def test_device_cli_blank_output(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual('', self.dev.cli('show configuration interfaces',
                                          warning=False))

    def test_device_cli_rpc_reply_with_message(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            '\nprotocol: operation-failed\nerror: device asdf not found\n',
            self.dev.cli('show interfaces terse asdf',
                         warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime| display xml rpc',
                                      warning=False)
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        val = self.dev.cli('foo')
        self.assertEqual(val, 'invalid command: foo: RpcError')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show system uptime').tag,
            'get-system-uptime-information')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            '<get-system-uptime-information>',
            self.dev.display_xml_rpc(
                'show system uptime',
                format='text'))

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show foo'),
            'invalid command: show foo| display xml rpc')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

# This test is for the commented out rpc-error code
#     def test_device_execute_exception(self):
#         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
#         self.assertRaises(RpcError, self.dev.execute,
#                           '<load-configuration-error/>')

    @patch('jnpr.junos.device.warnings')
    def test_device_execute_unknown_exception(self, mock_warnings):
        class MyException(Exception):
            pass
        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(
            EzErrors.PermissionError,
            self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(
            EzErrors.RpcTimeoutError,
            self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(
            EzErrors.ConnectClosedError,
            self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.__doc__,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                'tests/unit/templates/config-example.xml')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example.xml')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                                          'domain_name': '2'}),
                         'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch('ncclient.manager.connect')
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host='3.3.3.3', user='******',
                        password='******', gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name='_conn')
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False
                dev.close = MagicMock(name='close')
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        with open(fpath) as fp:
            foo = fp.read()

            if fname == 'get-rpc-error.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif fname == 'get-permission-denied.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif (fname == 'get-index-error.xml' or
                    fname == 'get-system-core-dumps.xml' or
                    fname == 'load-configuration-error.xml' or
                    fname == 'show-configuration-interfaces.xml' or
                  fname == 'show-interfaces-terse-asdf.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            elif (fname == 'show-configuration.xml' or
                  fname == 'show-system-alarms.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc
            elif fname == 'show-interface-terse.json':
                rpc_reply = json.loads(foo)
            elif fname == 'get-route-information.json':
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            else:
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs and 'normalize' not in kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                if args[0].text == 'show interface terse':
                    return self._read_file('show-interface-terse.json')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime| display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                elif args[0].text == 'show configuration interfaces':
                    return self._read_file('show-configuration-interfaces.xml')
                elif args[0].text == 'show interfaces terse asdf':
                    return self._read_file('show-interfaces-terse-asdf.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media':
                    return self._read_file(
                        'show-interfaces-routing-instance-media.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media| display ' \
                                     'xml rpc':
                    return self._read_file(
                        'show-interfaces-routing-instance-media-rpc.xml')
                else:
                    raise RpcError

            else:
                if args[0].attrib.get('format') == 'json':
                    return self._read_file(args[0].tag + '.json')
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
Ejemplo n.º 43
0
class pybot_jrouter(object):

    ROBOT_LIBRARY_SCOPE = 'TEST SUITE'

    ROBOT_LISTENER_API_VERSION = 2

# -----------------------------------------------------------------------
# CONSTRUCTOR
# -----------------------------------------------------------------------
    def __init__(self,**kvargs):
        """
            Constructor method. It takes a user, password and a target (port is optional) 
            arguments to create an instance of a JunOS device that will be used by RF
        """
        # Setting credentials 

        self.user = kvargs['user']
        self.target = kvargs['target']
        self.password = kvargs['password']
        try:
            self.port = int(kvargs['port'])
        except KeyError:
            self.port = 22
        self.ROBOT_LIBRARY_LISTENER = self
        self.max_retries = 2
        self._conn = Device(user=self.user, host=self.target, password=self.password, port=self.port, gather_facts=False)

# -----------------------------------------------------------------------
# OVERLOADS
# -----------------------------------------------------------------------
    def __repr__ (self):
        """
            Function that returns a representation of an instance of a JunOS device used by RF
        """
        return "pybot_jrouter: user=%s, target=%s, password=%s, port=%s, connection=%s" % (self.user, self.target, self.password, self.port, self._conn)


# -----------------------------------------------------------------------
# FUNCTIONS START HERE
# -----------------------------------------------------------------------

    def open_connection(self):
        """
            Function that opens a connection to a JunOS device
        """
        try:
            self._conn.open(auto_probe=10)
            self._conn.timeout = 120*120
            return self
        except ConnectError as c_error:
            print ("WARN Connection problems %s target: %s port: %s" % (c_error, self.target, self.port))
            raise ContinuableError("Connection problems %s target: %s port: %s" %(c_error, self.target, self.port))

    def close_connection(self):
        """
            Function that closes a connection to a JunOS device

        """
        try:
            self._conn.close()
            return self
        except ConnectError as c_error:
            print ("WARN Connection problems %s" %c_error)
            raise ContinuableError("Connection problems %s" %c_error)

    def load_configuration_from_file(self, synchronize=True, overwrite=False, **kvargs):

        """
            Function that load configuration on router from a file

            path : where the configuration file is located

            format:  possible values 'set' or 'xml' or 'bracket'  (so far only format 'set' is supported)

        """
        #overwrite = kvargs.pop ('overwrite',False)
        args = dict(data='')
        args.update(kvargs)
        if overwrite:
            return self.load_configuration(overwrite=True, **args)
        else:
            return self.load_configuration(overwrite=False, **args)

    def load_configuration_from_template(self,
                                            commit_comment='pybot_jrouter_load_configuration_from_template',
                                            format='set',
                                            conf_mode='exclusive',
                                            overwrite=False,
                                            merge=False,
                                            synchronize=True,
                                            force_synchronize=False,
                                            full=False,
                                            print_conf_diff=False,
                                            print_conf_detail=False,
                                            **kvargs):

        """
            # General Options:
                #     - format can be text/set/xml
                #     - print_conf_diff will print the diff if desired
                #     - print_conf_detail will print the committed configuration if desired
                # Configuration Options:
                #    - conf_mode: can be exclusive/private/dynamic/batch
                # Load Options:
                #    - overwrite: Determines if the contents completely replace the existing configuration.  Default is False
                #    - merge: If set to True will set the load-config action to merge the default load-config action is 'replace'
                # Commit Options:
                #    - kvargs synchronize: Default True. On dual control plane systems, requests that the candidate configuration on one control plane be copied to the other control plane, checked for correct syntax, and committed on both Routing Engines. Default is True.
                #    - kvargs force_synchronize: Default False. On dual control plane systems, forces the candidate configuration on one control plane to be copied to the other control plane. Default is False
                #    - kvargs full: Default False. When True requires all the daemons to check and evaluate the new configuration
        """
        print ("*INFO* Host %s|load_configuration_from_template|General Options: format=%s, print_conf_diff=%s, print_conf_detail=%s" % (self.target, format, print_conf_diff, print_conf_detail))

        synchronize = True
        force_synchronize = False
        full = False

        if 'force_synchronize' in kvargs.keys():
            force_synchronize = kvargs['force_synchronize']
        if 'synchronize' in kvargs.keys():
            synchronize = kvargs['synchronize']
        if 'full' in kvargs.keys():
            full = kvargs['full']

        ##Hidden variable: DO NOT USE  DO NOT EDIT
        #It will be set to True ONLY if routers.load_configuration_from_template_in_parallel is executed
        if 'parallel' in kvargs.keys():
            parallel = kvargs['parallel']
        else:
            parallel = False

        if force_synchronize:
            synchronize = True
            print ("*INFO* Host %s|load_configuration_from_template|Force Synchronized Commit requested" % (self.target))
        if synchronize:
            print ("*INFO* Host %s|load_configuration_from_template|Synchronized Commit requested" % (self.target))
        if full:
            print ("*INFO* Host %s|load_configuration_from_template|Commit Full requested" % (self.target))
        print ("*INFO* Host %s|load_configuration_from_template|Load Options: merge=%s, overwrite=%s" % (self.target, merge, overwrite))

        if format == 'set' and overwrite:
            overwrite = False
            print ("*WARN* Host %s|load_configuration_from_template|Not possible to override the configuration with format=set. Overwriting disabled." % (self.target))

        yaml_file = kvargs['template_vars']
        # Loading files and rendering
        myvars = yaml.load(open(yaml_file).read())

        loadResp = ''
        commitResp = False

        print ("*INFO* Host %s|load_configuration_from_template|Initializing variables. template_path=%s." % (self.target, kvargs['jinja2_file']))
        try:
            #Unlock/close configuration is managed by Config context manager
            with Config(self._conn, mode=conf_mode) as candidate:
                begin_load_datetime = datetime.now()
                if overwrite:
                    loadResp = candidate.load(template_path=kvargs['jinja2_file'], template_vars=myvars, format=format, overwrite=True, merge=merge)
                else:
                    loadResp = candidate.load(template_path=kvargs['jinja2_file'], template_vars=myvars, format=format, overwrite=False, merge=merge)
                finish_load_datetime = datetime.now()
                if loadResp.find("ok") is None:
                    print ("*WARN* Host %s|load_configuration_from_template|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp)))
                    return False

                if print_conf_diff:
                    try:
                        print ('*INFO* Host %s|load_configuration_from_template|DIFF configuration to be committed  %s' % (self.target, candidate.diff()))
                    except lxml.etree.XMLSyntaxError as error:
                        print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error))

                begin_commit_datetime = datetime.now()
                if print_conf_detail:
                    try:
                        #begin_commit_datetime=datetime.now()
                        commitResp = candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=True)
                        #finish_commit_datetime=datetime.now()
                        print ('*INFO* Host %s|load_configuration_from_template|Configuration to be committed:  %s' % (self.target, etree.tostring(commitResp)))
                    except lxml.etree.XMLSyntaxError as error:
                        print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the committed configuration. Printout will be skipped, check the node or try again with print_conf_detail=False....: %s" % (self.target, error))
                        return False
                else:
                    begin_commit_datetime = datetime.now()
                    commitResp = candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=False)
                    finish_commit_datetime = datetime.now()
        except LockError as lockError:
            print ("*WARN* Host %s|load_configuration_from_template|Problems locking configuration: %s" % (self.target, lockError))
            if parallel:
                return "Exception %s:" %lockError
            else:
                raise FatalError("Host %s|load_configuration_from_template|Unable to lock configuration.....exiting: %s" % (self.target, lockError))
        except (RpcError, RpcTimeoutError) as rpcError:
            #warnings severity is already being ignored in the Config context manager
            print ("*WARN* Host %s|load_configuration_from_template|Problems opening configuration: %s" % (self.target, rpcError))
            if parallel:
                return "Exception %s:" %rpcError
            else:
                raise FatalError("Host %s|load_configuration_from_template|Unable to open configuration.....exiting: %s" % (self.target, rpcError))
        except ConfigLoadError as configError:
            print( "*WARN* Host %s|load_configuration_from_template|Template %s|Problems loading the configuration: %s.....exiting" % (self.target, kvargs['jinja2_file'], configError))
            if print_conf_diff:
                try:
                    print ('*INFO* Host %s|load_configuration_from_template|DIFF configuration to be committed  %s' % (self.target, candidate.diff()))
                except lxml.etree.XMLSyntaxError as error:
                    print ("*WARN* Host %s|load_configuration_from_template|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error))
            if parallel:
                return "Exception %s:" %configError
            else:
                raise FatalError("Host %s|load_configuration_from_template|Template %s|Unable to load the configuration.....exiting: %s" % (self.target, kvargs['jinja2_file'], configError))
        except CommitError as commitError:
            print ("*WARN* Host %s|load_configuration_from_template|Template %s|Problems committing the configuration: %s.....exiting" % (self.target, kvargs['jinja2_file'], commitError))
            if parallel:
                return "Exception %s:" %commitError
            else:
                raise FatalError("Host %s|load_configuration_from_template|Template %s|Unable to commit the configuration.....exiting: %s" % (self.target, kvargs['jinja2_file'], commitError))
        except UnlockError as unlockError:
            print ("*WARN* Host %s|load_configuration_from_template|Problems unlocking the configuration: %s.....exiting" % (self.target, unlockError))
            if parallel:
                return "Exception %s:" %unlockError
            else:
                raise FatalError("Host %s|load_configuration_from_template|Unable to unlock the configuration.....exiting: %s" % (self.target, unlockError))
        except Exception as error:
            if 'Opening and ending tag mismatch: routing-engine ' in error:
                print ('*INFO* Host %s|load_configuration_from_template|%s' %(self.target, error))
                pass
                return True
            else:
                print ("*WARN* Host %s|load_configuration_from_template|An unhandled exception occurred: %s.....exiting" % (self.target, error))
                if parallel:
                    return "Exception %s:" %error
                else:
                    raise FatalError("Host %s|load_configuration_from_template|Unhandled Exception occurred.....exiting: %s" % (self.target, error))

        diff_load_time = finish_load_datetime - begin_load_datetime
        diff_commit_time = finish_commit_datetime - begin_commit_datetime
        total_time = finish_commit_datetime - finish_load_datetime
        print ('*INFO* Host %s|load_configuration_from_template|Configuration successfully committed|Template: %s|Load Time: %s|Commit Time: %s| Total Time: %s' % (self.target, kvargs['jinja2_file'], self.pretty_time_delta(diff_load_time.seconds), self.pretty_time_delta(diff_commit_time.seconds), self.pretty_time_delta(total_time.seconds)))

        return True


    def load_configuration(self,
                            commit_comment ='pybot_jrouter_load_configuration',
                            path=None,
                            format='set',
                            conf_mode='exclusive',
                            overwrite=False,
                            merge=False,
                            synchronize=True,
                            force_synchronize=False,
                            full=False,
                            print_conf_diff=False,
                            print_conf_detail=False,
                            **kvargs):

        """
            Function that load configuration on a JunOS device

            **kvargs    format:set|text|xml
                        data: data to load in the router
        """

        print ("*INFO* Host %s|load_configuration|General Options: format=%s, print_conf_diff=%s, print_conf_detail=%s" % (self.target, format, print_conf_diff, print_conf_detail))

        data = kvargs['data']
        format = kvargs['format']

        if 'force_synchronize' in kvargs.keys():
            force_synchronize = kvargs['force_synchronize']
        if 'synchronize' in kvargs.keys():
            synchronize = kvargs['synchronize']
        if 'full' in kvargs.keys():
            full = kvargs['full']

        if force_synchronize:
            synchronize = True
            print ("*INFO* Host %s|load_configuration|Force Synchronized Commit requested" % (self.target))
        if synchronize:
            print ("*INFO* Host %s|load_configuration|Synchronized Commit requested" % (self.target))
        if full:
            print ("*INFO* Host %s|load_configuration|Commit Full requested" % (self.target))

        print ("*INFO* Host %s|load_configuration|Load Options: merge=%s, overwrite=%s" % (self.target, merge, overwrite))

        if format == 'set' and overwrite:
            overwrite = False
            print ("*WARN* Host %s|load_configuration|Not possible to override the configuration with format=set. Overwriting disabled." % (self.target))

        loadResp = ''
        commitResp = False

        print ("*INFO* Host %s|load_configuration|Initializing variables. path=%s." % (self.target,path))
        print ("*INFO* Host %s|load_configuration|Initializing variables. data=%s." % (self.target,data))
        try:
            #Unlock/close configuration is managed by Config context manager
            with Config(self._conn, mode=conf_mode) as candidate:
                #begin_load_datetime=datetime.now()
                if ((data == "") and (path != None)):
                    if overwrite:
                        loadResp=candidate.load(path=path, format=format, overwrite=True, merge=merge)
                    else:
                        loadResp=candidate.load(path=path, format=format, overwrite=False, merge=merge)
                    #finish_load_datetime=datetime.now()
                    if loadResp.find("ok") is None:
                        print ("*WARN* Host %s|load_configuration|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp)))
                        return False

                    if print_conf_diff:
                        try:
                            print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed  %s' % (self.target, candidate.diff()))
                        except lxml.etree.XMLSyntaxError as error:
                            print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error))

                else:
                    if overwrite:
                        loadResp=candidate.load(data, format=format, overwrite=True, merge=merge)
                    else:
                        loadResp=candidate.load(data, format=format, overwrite=False, merge=merge)
                    #finish_load_datetime=datetime.now()
                    if loadResp.find("ok") is None:
                        print ("*WARN* Host %s|load_configuration|Load Response did not throw an exception but something unexpected occurred: %s" % (self.target, etree.tostring(loadResp)))
                        return False

                    if print_conf_diff:
                        try:
                            print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed  %s' % (self.target, candidate.diff()))
                        except lxml.etree.XMLSyntaxError as error:
                            print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error))

                #begin_commit_datetime=datetime.now()
                if print_conf_detail:
                    try:
                        #begin_commit_datetime=datetime.now()
                        commitResp=candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=True)
                        #finish_commit_datetime=datetime.now()
                        print ('*INFO* Host %s|load_configuration|Configuration to be committed:  %s' % (self.target, etree.tostring(commitResp)))
                    except lxml.etree.XMLSyntaxError as error:
                        print ("*WARN* Host %s|load_configuration|Unable to retrieve the commited configuration. Printout will be skipped, check the node or try again with print_conf_detail=False....: %s" % (self.target, error))
                        return False
                else:
                    #begin_commit_datetime=datetime.now()
                    commitResp=candidate.commit(comment=commit_comment, sync=synchronize, force_sync=force_synchronize, full=full, detail=False)
                    #finish_commit_datetime=datetime.now()
        except LockError as lockError:
            print ("*WARN* Host %s|load_configuration|Problems locking configuration: %s" % (self.target, lockError))
            raise FatalError("Host %s|load_configuration|Unable to lock configuration.....exiting: %s" % (self.target, lockError))
        except (RpcError,RpcTimeoutError) as rpcError:
            #warnings severity is already being ignored in the Config context manager
            print ("*WARN* Host %s|load_configuration|Problems opening configuration: %s" % (self.target, rpcError))
            raise FatalError("Host %s|load_configuration|Unable to open configuration.....exiting: %s" % (self.target, rpcError))
        except ConfigLoadError as configError:
            print ("*WARN* Host %s|load_configuration|Problems loading the configuration: %s.....exiting" % (self.target, configError))
            if print_conf_diff:
                try:
                    print ('*INFO* Host %s|load_configuration|DIFF configuration to be committed  %s' % (self.target, candidate.diff()))
                except lxml.etree.XMLSyntaxError as error:
                    print ("*WARN* Host %s|load_configuration|Unable to retrieve the DIFF configuration to be committed. Printout will be skipped, trying to commit....: %s" % (self.target, error))
            raise FatalError("Host %s|load_configuration|Unable to load the configuration.....exiting: %s" % (self.target, configError))
        except CommitError as commitError:
            print ("*WARN* Host %s|load_configuration|Problems committing the configuration: %s.....exiting" % (self.target, commitError))
            raise FatalError("Host %s|load_configuration|Unable to commit the configuration.....exiting: %s" % (self.target, commitError))
        except UnlockError as unlockError:
            print ("*WARN* Host %s|load_configuration|Problems unlocking the configuration: %s.....exiting" % (self.target, unlockError))
            raise FatalError("Host %s|load_configuration|Unable to unlock the configuration.....exiting: %s" % (self.target, unlockError))
        except Exception as error:
            if 'Opening and ending tag mismatch: routing-engine ' in error:
                print ('*INFO* Host %s|load_configuration|%s' % (self.target, error))
                pass
                return True
            else:
                print ("*WARN* Host %s|load_configuration|An unhandled exception occurred: %s.....exiting" % (self.target, error))
                raise FatalError("Host %s|load_configuration|Unhandled Exception occurred.....exiting: %s" % (self.target, error))

        print ('*INFO* Host %s|load_configuration|Configuration successfully committed' % (self.target))
        #diff_load_time=begin_load_datetime-finish_load_datetime
        #diff_commit_time=begin_commit_datetime-finish_commit_datetime
        return True

    def jsnap(self, **kvargs):

        """
            Function that makes use of JSNAP

        """
        variables = BuiltIn().get_variables()

        # Assigning kvargs

        section = None


        if 'section' in kvargs.keys():
            section = kvargs['section']
        tag = kvargs['tag']
        snaptype = kvargs['snaptype']
        test = kvargs['test']
        mode = kvargs['mode']
        output_directory = variables['${path}']
        test_case = variables['${testname}']

        tmp_dir = tempfile.mkdtemp(prefix='_')
        dirpath = output_directory + "/" + tmp_dir + "/" + test_case.replace(" ","_") + "/" + self.target + "/snapshot/"

        #PARENT_ROOT=os.path.abspath(os.path.join(self.logdir, os.pardir))
        #GRANDPA=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir))

        if not os.path.exists(dirpath):
            os.makedirs(dirpath, mode=777)

        timestamp = datetime.now().strftime("%Y-%m-%d")

        if snaptype == "snap":

            if section:
                cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' -s' + section + ' ' + test
            else:
                cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' ' + test
            print ("Executing: %s" %cmd)
            jsnap_command = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, shell=True, cwd=dirpath)
            output, errors = jsnap_command.communicate()
            if ((("Exiting." in errors)) or("Unable to connect to device: " in errors) or ("jsnap: not found" in errors) or ("appears to be missing" in output)):
                print (output)
                print (errors)
                raise FatalError("Unable to execute jsnap.....exiting")
            else:
                return True
            print (output, errors)
            return True

        elif snaptype == "snapcheck":

            if section:
                cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target + ' -s' + section + ' ' + test
            else:
                cmd = 'jsnap --'+ snaptype + " " + timestamp + '_'+ tag + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target  + ' ' + test
            print ("Executing: %s" %cmd)
            jsnap_command = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, shell=True, cwd=dirpath)
            output, errors = jsnap_command.communicate()

            print (output)
            print (errors)

            if ((("Exiting." in errors)) or ("Unable to connect to device: " in errors) or ("jsnap: not found" in errors) or ("appears to be missing" in output)):

                print (output)
                print (errors)
                raise FatalError("Unable to execute jsnap.....exiting")

            else:
                if mode == "strict":
                    if "ERROR" in output or "ERROR" in errors:
                        raise FatalError("ERROR found in jsnap mode strict.....exiting")
                    else:
                        return True
                else:
                    return True

        elif snaptype == "check":

            if section:
                cmd_check = 'jsnap --'+ snaptype + " " + timestamp + '_pre' + ',' +  timestamp + '_post' + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target  + ' -s' + section + ' ' + test
            else:
                cmd_check = 'jsnap --'+ snaptype + " " + timestamp + '_pre' + ',' +  timestamp + '_post' + ' -l ' + self.user + ' -p ' + self.password + ' -t ' + self.target  + ' '  + test
            print ("Executing: %s" %cmd_check)
            jsnap_command = sub.Popen(cmd_check, stdout=sub.PIPE, stderr=sub.PIPE, shell=True, cwd=dirpath)
            output, errors = jsnap_command.communicate()
            print (output)
            print (errors)

            if ((("Exiting." in errors)) or ("Unable to connect to device: " in errors) or ("jsnap: not found" in errors) or ("appears to be missing" in output)):

                print (output)
                print (errors)
                raise FatalError("Unable to execute jsnap.....exiting")

            else:
                if mode == "strict":
                    if "ERROR" in output or "ERROR" in errors:
                        raise FatalError("ERROR found in jsnap mode strict.....exiting")
                    else:
                        return True
                else:

                    return True
        else:
            raise FatalError("Invalid snap type.....exiting")


    def rescue_configuration(self, print_diff=False, **kvargs):

        """
            Function that issues Save/Load a Rescue Configuration

        """

        if 'action' in kvargs.keys():
            action = kvargs['action']

        # Saving rescue configuration
        if action == 'save':
            try:
                self._conn.rpc.request_save_rescue_configuration()
            except RpcError as err:
                rpc_error = err.__repr__()
                print (rpc_error)
            return self
        # Checking if this attribute was already attached to Device
        if hasattr(self._conn, "candidate"):
            pass
        else:
            self._conn.bind(candidate=Config)

        # Locking configuration
        try:
            self._conn.candidate.lock()
        except LockError as l_error:
            print ("*WARN* Problems locking configuration: %s" % (l_error))
            raise FatalError("Unable to lock configuration.....exiting")

        # Loading rescue configuration
        if action == 'load':
            try:
                self._conn.rpc.load_configuration({'rescue': 'rescue'})
            except RpcError as err:
                rpc_error = err.__repr__()
                print (rpc_error)
            except ConfigLoadError as error:
                print ("*WARN* Problems loading configuration: %s" % (error))
                raise FatalError("Unable to load configuration.....exiting")
            if print_diff:
                print ('*INFO* Configuration to be commited  %s' % (self._conn.candidate.diff()))

            try:
                self._conn.candidate.commit(comment='loading rescue configuration')
                self._conn.candidate.unlock()
                return True

            except (CommitError, LockError) as err:
                print (err)
                raise FatalError("Unable to commit or unlock configuration......exiting")

    def commands_executor(self, **kvargs):

        """
            Function that issues commands

        """

        # Getting RF built-in variables
        variables = BuiltIn().get_variables()

        regex = ''
        xpath = ''
        if 'xpath' in kvargs.keys():
            xpath = kvargs['xpath']

        if 'regex' in kvargs.keys():
            regex = kvargs['regex']

        if 'output_dir' in kvargs.keys():
            output_directory = kvargs['output_dir']
        else:
            output_directory = variables['${path}']

        command = kvargs['command']
        format = kvargs['format']

        root_dir = variables['${OUTPUT_DIR}']
        test_case = variables['${testname}']

        if format == "text":

            # tmp_dir = tempfile.mkdtemp(prefix='_')
            # if output_directory == None:
            #     dirpath = "/collector/" + tmp_dir + "/" + timestamp + "/"
            # else:
            #     dirpath = output_directory + "/" + tmp_dir + "/" + test_case.replace(" ", "_") + "/commands"

            # Create directory if does not exist
            # if not os.path.exists(dirpath):
            #     os.makedirs(dirpath, mode=0777)

            if regex:

                try:
                    cmd_to_execute = self._conn.rpc.cli(command)
                except RpcError as err:
                    rpc_error = err.__repr__()
                    print (xmltodict.parse(rpc_error)['rpc-error']['error-message'])
                    raise FatalError("Error executing RPC,exiting...")

                operations = command.split("|")[1:]
                result_tmp = cmd_to_execute.text
                lines = result_tmp.strip().split('\n')
                for operation in operations:
                    if re.search("count", operation, re.IGNORECASE):
                        print ('*INFO* Count: %s lines' % len(lines))
                        return len(lines)
                    match = re.search('match "?(.*)"?', operation, re.IGNORECASE)
                    if match:
                        regex = match.group(1).strip()
                        lines_filtered = []
                        for line in lines:
                            if re.search(regex, line, re.IGNORECASE):
                                lines_filtered.append(line)
                        lines = lines_filtered
                    match = re.search('except "?(.*)"?', operation, re.IGNORECASE)
                    if match:
                        regex = match.group(1).strip()
                        lines_filtered = []
                        for line in lines:
                            if re.search(regex, line, re.IGNORECASE):
                                pass
                            else:
                                lines_filtered.append(line)
                        lines = lines_filtered

                text_matches = re.search(regex, cmd_to_execute.text, re.MULTILINE)

                if text_matches:
                    print (text_matches.groups())
                    return text_matches.groups()
            else:
                print ("Executing: %s" %command)

                try:
                    cmd_to_execute = self._conn.rpc.cli(command)

                except RpcError as err:
                    rpc_error = err.__repr__()
                    print (xmltodict.parse(rpc_error)['rpc-error']['error-message'])
                    raise FatalError("Error executing RPC,exiting...")

                # #print (type(cmd_to_execute))
                # if isinstance(cmd_to_execute, bool):
                #     return True
                # else:
                #     cmd_clean = command.replace(" ", "_").replace('_"', '_').replace('"_', '_').replace('"', '').replace("/", "_")
                #     filename = timestamp2 + '_'+ self.target  + "_" + cmd_clean + "." + "txt"
                #     path = os.path.join(dirpath, filename).replace(root_dir, '.')
                #     print ("Saving file as: %s" %path)
                #     print ('*HTML* <a href="%s" target="_blank">%s</a>' % (path, path))

                #     try:
                #         with open(path, 'w') as file_to_save:
                #             file_to_save.write(cmd_to_execute.text)
                #         return True
                #     except IOError as err:
                #         print (err.errno, err.strerror)
                #         raise FatalError("Error opening File, exiting...")

        elif format == "xml":

            if xpath:
                print ("Executing: %s [%s]" %(command, xpath))

                try:
                    cmd_to_execute = self._conn.rpc.cli(command, format='xml')
                    xml_result = etree.tostring(cmd_to_execute)

                except RpcError as err:
                    rpc_error = err.__repr__()
                    print (xmltodict.parse(rpc_error)['rpc-error']['error-message'])
                    raise FatalError("Error executing RPC, exiting...")

                xpath_result = cmd_to_execute.xpath(xpath)[0].text.strip()

                if xpath_result == None:
                    raise FatalError("XPATH malformed, exiting...")
                else:
                    print (xpath_result)
                    return xpath_result
            else:
                try:
                    cmd_to_execute = self._conn.rpc.cli(command, format='xml')
                    xml_result = etree.tostring(cmd_to_execute)

                except RpcError as err:
                    rpc_error = err.__repr__()
                    print (xmltodict.parse(rpc_error)['rpc-error']['error-message'])
                    raise FatalError("Error executing RPC, exiting...")
                return xml_result
        else:
            raise FatalError("Format not valid, exiting...")

    def save_config_to_file(self, **kvargs):
        """
            Function that saves a configuration to a file in a JunOS device

        """
        directory = kvargs['directory'] + '/' + timestamp4
        print ("*INFO* Saving current configuration...")
        file_obj = StartShell(self._conn)
        file_obj.open()
        got = file_obj.run("cli -c 'show configuration | save " + directory + "_config.txt' ")
        file_obj.close()
        print ("*INFO* %s" % (got))
        return got[-2].split("'")[1]

    def rollback(self, commit_comment='__JRouter__', **kvargs):
        """
            Function that performs rollback
                rollback_num = number

        """
        rollback_num = kvargs['rollback_num']

        try:
            rollback_num = int(rollback_num)
            if rollback_num > 50:
                raise FatalError("Sorry. 'rollback_num' must lower than 50")
        except Exception as e:
            raise FatalError("Sorry. 'rollback_num' must be an integer.")

        if hasattr(self._conn, "candidate"):
            pass
        else:
            self._conn.bind(candidate=Config)
        try:
            self._conn.candidate.lock()
        except LockError as l_error:
            print ("*WARN* Problems locking configuration: %s" % (l_error))
            raise FatalError("Unable to lock configuration... exiting")

        try:
            print ("Rolling back configuration....")
            self._conn.candidate.rollback(rollback_num)
            self._conn.candidate.commit(comment=commit_comment)
            self._conn.candidate.unlock()
            return True
        except RpcError as err:
            rpc_error = err.__repr__()
            raise FatalError(xmltodict.parse(rpc_error)['rpc-error']['error-message'])

    def _is_dual_RE (self):
    
        """
            Auxiliar function that returns True if the system is dual-RE and both RE are available
        """

        if self._conn.facts['2RE']:
            return True
        else:
            return False

    def reboot_re (self,**kvargs):
            
        """
            Function for rebooting backup RE
            
            **kvargs 
                role: master/backup                
        """
        try:
            role = kvargs['role']
        except KeyError:
            raise ContinuableError("Missing Key....role")
        # Dual RE and role backup
        if self._is_dual_RE () and role == 'backup': 

            try:
                print ("Rebooting Backup Routing Engine....")
                self._conn.rpc.request_reboot(other_routing_engine=True)
                # sleeping to avoid quick return
                sleep (60)
                return True 
            except RpcError as err:    
                raise ContinuableError("Error executing RPC... {0}".format(err))

        # Single RE or DUAL-RE system capabable with only 1 available RE
        else:                    
            try:
                print ("Rebooting Master Routing Engine....")
                self._conn.rpc.request_reboot()         
                self._conn.close ()
                # sleeping to avoid quick return
                sleep (60)
                try:
                    self._conn.open(auto_probe=600)
                    return True
                except ConnectError as c_error:
                    raise ContinuableError("ERROR: Routing Engine is not Online after 10 min" + str(c_error))
            except RpcError as err:
                raise ContinuableError("Error executing RPC... {0}".format(err))

    def switchover(self):
        """
            Function to perfom RE switchover
        """
        # We need to verify that backup RE is ready before proceed
        b_slot = self.get_slot('backup')
        b_state = self._conn.rpc.get_route_engine_information(slot=b_slot)
        state = b_state.findtext('route-engine/mastership-state')

        if (state != "backup"):
            raise FatalError("Backup RE is not ready")

        try:
            self.open_connection()
            print ('Executing switchover to complete the SW upgrade !!!')
            switchover_cmd = self._conn.cli("request chassis routing-engine master switch no-confirm", format='xml', warning=False)
            self.close_connection()
        except ConnectError as c_error:
            raise FatalError(c_error)
        # except TError.TimeoutExpiredError as Terr:
        #     print (Terr)
        #     pass
        # except NcErrors.SessionCloseError as Serr:
        #     print (Serr)
        #     pass
        except SocketError as S_err:
            print (S_err)
            pass
        except ConnectClosedError as CC_error:
            print (CC_error)
            pass

        sleep(60)
        try:
            # WA for dealing with in band connections
            print ("Re-opening connection.......")
            self._conn.open(auto_probe=900)
            return True
        except ConnectError as c_error:
            raise FatalError(c_error)

    def reboot (self):      
        """
            Function for rebooting both RE         
        """
        
        # Dual RE and role backup

        try:
            print ("Rebooting Both Routing Engines....")
            cmd = self._conn.rpc.request_reboot(both_routing_engines=True)
            # sleeping to avoid quick return
            sleep (60)
            return True 
        except RpcError as err:    
            raise FatalError("Error executing RPC... %s" %err)

    def get_routing_table(self, **kvargs):
        """
            Function that gathers the routing table from a device. It returns the whole routing table if no route is specified.
            If route is specified, next_hop can be also specified and routing table nexthop output will be compared against it.
        """
        try:
            tbl = RouteTable(self._conn)
        except ConnectError as c_error:
            raise FatalError(c_error)

        complete_rt = tbl.get()
        if 'route' in kvargs.keys():
            route = kvargs['route']
        print ('route', route)
        if route != 'None':
            single_rt = tbl.get(route)

        # Routing Table dictionary
        rt = {}
        for item in tbl:
            # Remove "RouteTableView:" from item = RouteTableView:0.0.0.0/0
            destination = str(item).split(":")[1]
            rt[destination] = [item.nexthop, item.age, item.via, item.protocol]

        return rt

    def pretty_time_delta(self, seconds):
        """
            Helper function that returns formatted time     
        """
        sign_string = '-' if seconds < 0 else ''
        seconds = abs(int(seconds))
        days, seconds = divmod(seconds, 86400)
        hours, seconds = divmod(seconds, 3600)
        minutes, seconds = divmod(seconds, 60)
        if days > 0:
            return '%s%dd%dh%dm%ds' % (sign_string, days, hours, minutes, seconds)
        elif hours > 0:
            return '%s%dh%dm%ds' % (sign_string, hours, minutes, seconds)
        elif minutes > 0:
            return '%s%dm%ds' % (sign_string, minutes, seconds)
        else:
            return '%s%ds' % (sign_string, seconds)


    def get_config(self, xml_filter=None):
        """
            Function that returns a piece of a JunOS device configuration      
        """
        if xml_filter is None:
            cnf = self._conn.rpc.get_config()
        else:
            # Should user wants to filter out configuration and extract only a piece of it
            # e.g. SNMP
            #cnf = dev.rpc.get_config(filter_xml=etree.XML('<snmp></snmp>'))
            # interfaces
            #cnf = dev.rpc.get_config(filter_xml=etree.XML('<configuration><interfaces/></configuration>'))
            cnf = self._conn.rpc.get_config(filter_xml=etree.XML(xml_filter))
        #print (etree.tostring(cnf))
        config = etree.tostring(cnf)
        #print (config)
        return config
Ejemplo n.º 44
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko,
                              mock_connect, mock_proxy):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_any()

    def test_scp_progress(self):
        scp = SCP(self.dev)
        print(scp._scp_progress('test', 100, 50))

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_user_def_progress(self, mock_scpclient, mock_put, mock_ssh):
        mock_scpclient.return_value = None

        def fn(file, total, tfd):
            pass

        package = 'test.tgz'
        with SCP(self.dev, progress=fn) as scp:
            scp.put(package)
        self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__,
                         'fn')

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_user_def_progress_args_2(self, mock_scpclient, mock_put,
                                          mock_ssh):
        mock_scpclient.return_value = None

        def myprogress(dev, report):
            print("host: %s, report: %s" % (dev.hostname, report))

        package = 'test.tgz'
        with SCP(self.dev, progress=myprogress) as scp:
            scp.put(package)
        self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__,
                         '_scp_progress')

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_progress_true(self, mock_scpclient, mock_put, mock_sshclient):
        mock_scpclient.return_value = None
        package = 'test.tgz'
        with SCP(self.dev, progress=True) as scp:
            scp.put(package)
        self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__,
                         '_scp_progress')

    @contextmanager
    def capture(self, command, *args, **kwargs):
        out, sys.stdout = sys.stdout, StringIO()
        command(*args, **kwargs)
        sys.stdout.seek(0)
        yield sys.stdout.read()
        sys.stdout = out
Ejemplo n.º 45
0
    if int(ipaddr) >= ipnet.first and int(ipaddr) <= ipnet.last:
        return True
    else:
        return False

parser = argparse.ArgumentParser(description='Process user input')
parser.add_argument("--host", dest="hostname", default="",metavar="HOST",help="Specify host to connect to")
parser.add_argument("--username", dest="username", metavar="USERNAME",help="Specify the username")
parser.add_argument("--password", dest="password", metavar="PASSWORD",help="Specify the password")
parser.add_argument("--subnet", dest="subnet", metavar="SUBNET",help="Specify the subnet to check interfaces against")
args = parser.parse_args()

if args.hostname != "" and args.username != "" and args.password != "":
    dev = Device(user=args.username, host=args.hostname, password=args.password)
    dev.bind(cu=Config)
    dev.open()
    cfg = dev.rpc.get_config()
    dd = xmltodict.parse(ET.tostring(cfg,encoding="utf8", method="xml"))

    if "configuration" in dd:
        if "interfaces" in dd["configuration"]:
            if "interface" in dd["configuration"]["interfaces"]:
                for i in dd["configuration"]["interfaces"]["interface"]:
                    if "unit" in i:
                        if "family" in i["unit"]:
                            if "inet" in i["unit"]["family"]:
                                if "address" in i["unit"]["family"]["inet"]:
                                    if "name" in i["unit"]["family"]["inet"]["address"]:
                                        int_name = i["name"]
                                        test_ip = string.split(i["unit"]["family"]["inet"]["address"]["name"],"/")[0]
Ejemplo n.º 46
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'cannot open'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime + timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch('__builtin__.open', mock):
            with patch('__builtin__.file', MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_any()

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(host='2.2.2.2', user='******', password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            assert self.dev.facts['version'] == facts['version']

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'rick')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory').tag, 'cli')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms'))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime | display xml rpc')\
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

    def test_device_execute_exception(self):
        class MyException(Exception):
            rpc_err = """
<rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<error-severity>error</error-severity>
<error-info>
<bad-element>get-bgp-summary-information</bad-element>
</error-info>
<error-message>permission denied</error-message>
</rpc-error>                
            """
            xml = etree.XML(rpc_err)

        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(RpcError, self.dev.execute, 
            '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.func_doc,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            #for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            #for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template('tests/unit/templates/config-example')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                               'domain_name': '2'}),
                               'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        foo = open(fpath).read()

        if (fname == 'get-rpc-error.xml' or
                fname == 'get-index-error.xml' or
                fname == 'get-system-core-dumps.xml'):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())
        elif (fname == 'show-configuration.xml' or
              fname == 'show-system-alarms.xml'):
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc
        else:
            rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                  .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)

        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime | display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                else:
                    raise RpcError

            else:
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
Ejemplo n.º 47
0
class TestScp(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')

    @patch('paramiko.SSHClient')
    def test_scp_open(self, mock_connect):
        from scp import SCPClient
        self.dev.bind(scp=SCP)
        assert isinstance(self.dev.scp.open(), SCPClient)

    @patch('paramiko.SSHClient')
    def test_scp_close(self, mock_connect):
        self.dev.bind(scp=SCP)
        self.dev.scp.open()
        self.assertEqual(self.dev.scp.close(), None)

    @patch('paramiko.SSHClient')
    def test_scp_context(self, mock_connect):
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')

    @patch('jnpr.junos.device.os')
    @patch('__builtin__.open')
    @patch('paramiko.config.SSHConfig.lookup')
    @patch('paramiko.SSHClient')
    @patch('paramiko.proxy.ProxyCommand')
    def test_scp_proxycommand(self, os_mock, open_mock, mock_paramiko,
                              mock_connect, mock_proxy):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_path = '/home/rsherman/.ssh/config'
        with SCP(self.dev) as scp:
            scp.get('addrbook.conf')
        mock_proxy.assert_called_any()

    def test_scp_progress(self):
        scp = SCP(self.dev)
        print scp._scp_progress('test', 100, 50)

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_user_def_progress(self, mock_scpclient, mock_put, mock_ssh):
        mock_scpclient.return_value = None

        def fn(file, total, tfd):
            pass
        package = 'test.tgz'
        with SCP(self.dev, progress=fn) as scp:
            scp.put(package)
        self.assertEqual(
            mock_scpclient.mock_calls[0][2]['progress'].func_name, 'fn')

    @patch('paramiko.SSHClient')
    @patch('scp.SCPClient.put')
    @patch('scp.SCPClient.__init__')
    def test_scp_progress_true(self, mock_scpclient, mock_put, mock_sshclient):
        mock_scpclient.return_value = None
        package = 'test.tgz'
        with SCP(self.dev, progress=True) as scp:
            scp.put(package)
        self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].func_name,
                         '_scp_progress')

    @contextmanager
    def capture(self, command, *args, **kwargs):
        out, sys.stdout = sys.stdout, StringIO()
        command(*args, **kwargs)
        sys.stdout.seek(0)
        yield sys.stdout.read()
        sys.stdout = out
Ejemplo n.º 48
0
class JunOSDriver(NetworkDriver):

    def __init__(self, hostname, username, password, timeout=60):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.timeout = timeout
        self.device = Device(hostname, user=username, password=password)
        self.config_replace = False

    def open(self):
        self.device.open()
        self.device.timeout = self.timeout
        self.device.bind(cu=Config)
        self.device.cu.lock()

    def close(self):
        self.device.cu.unlock()
        self.device.close()

    def _load_candidate(self, filename, config, overwrite):
        if filename is None:
            configuration = config
        else:
            with open(filename) as f:
                configuration = f.read()

        try:
            self.device.cu.load(configuration, format='text', overwrite=overwrite)
        except ConfigLoadError as e:
            if self.config_replace:
                raise ReplaceConfigException(e.message)
            else:
                raise MergeConfigException(e.message)

    def load_replace_candidate(self, filename=None, config=None):
        self.config_replace = True
        self._load_candidate(filename, config, True)

    def load_merge_candidate(self, filename=None, config=None):
        self.config_replace = False
        self._load_candidate(filename, config, False)

    def compare_config(self):
        diff = self.device.cu.diff()

        if diff is None:
            return ''
        else:
            return diff.strip()

    def commit_config(self):
        self.device.cu.commit()

    def discard_config(self):
        self.device.cu.rollback(rb_id=0)

    def rollback(self):
        self.device.cu.rollback(rb_id=1)
        self.commit_config()

    def get_facts(self):

        output = self.device.facts

        uptime = 0
        if 'RE0' in output:
            uptime = output['RE0']['up_time']

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()
        interface_list = interfaces.keys()

        return {
            'vendor': u'Juniper',
            'model': unicode(output['model']),
            'serial_number': unicode(output['serialnumber']),
            'os_version': unicode(output['version']),
            'hostname': unicode(output['hostname']),
            'fqdn': unicode(output['fqdn']),
            'uptime': string_parsers.convert_uptime_string_seconds(uptime),
            'interface_list': interface_list
        }

    def get_interfaces(self):

        # init result dict
        result = {}

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()

        # convert all the tuples to our pre-defined dict structure
        for iface in interfaces.keys():
            result[iface] = {
                'is_up': interfaces[iface]['is_up'],
                'is_enabled': interfaces[iface]['is_enabled'],
                'description': interfaces[iface]['description'] or u'',
                'last_flapped': interfaces[iface]['last_flapped'] or -1,
                'mac_address': unicode(interfaces[iface]['mac_address'])
            }
            result[iface]['last_flapped'] = float(result[iface]['last_flapped'])

            match = re.search(r'\d+', interfaces[iface]['speed'] or '')
            if match is not None:
                result[iface]['speed'] = int(match.group(0))
            else:
                result[iface]['speed'] = -1

        return result

    def get_interfaces_counters(self):
        query = junos_views.junos_iface_counter_table(self.device)
        query.get()
        interface_counters = dict()
        for interface, counters in query.items():
            interface_counters[interface] = {k: v or -1 for k, v in counters}
        return interface_counters

    def get_environment(self):
        environment = junos_views.junos_enviroment_table(self.device)
        routing_engine = junos_views.junos_routing_engine_table(self.device)
        temperature_thresholds = junos_views.junos_temperature_thresholds(self.device)
        environment.get()
        routing_engine.get()
        temperature_thresholds.get()
        environment_data = dict()

        for sensor_object, object_data in environment.items():
            structured_object_data = {k: v for k, v in object_data}

            if structured_object_data['class'] == 'Power':
                # Create a dict for the 'power' key
                try:
                    environment_data['power'][sensor_object] = dict()
                except KeyError:
                    environment_data['power'] = dict()
                    environment_data['power'][sensor_object] = dict()

                # Set these values to -1, because Junos does not provide them
                environment_data['power'][sensor_object]['capacity'] = -1.0
                environment_data['power'][sensor_object]['output'] = -1.0

            if structured_object_data['class'] == 'Fans':
                # Create a dict for the 'fans' key
                try:
                    environment_data['fans'][sensor_object] = dict()
                except KeyError:
                    environment_data['fans'] = dict()
                    environment_data['fans'][sensor_object] = dict()

            if structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Power':
                # If status is Failed, Absent or Testing, set status to False.
                environment_data['power'][sensor_object]['status'] = True

            elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Power':
                environment_data['power'][sensor_object]['status'] = False

            elif structured_object_data['status'] == 'OK' and structured_object_data['class'] == 'Fans':
                # If status is Failed, Absent or Testing, set status to False.
                environment_data['fans'][sensor_object]['status'] = True

            elif structured_object_data['status'] != 'OK' and structured_object_data['class'] == 'Fans':
                environment_data['fans'][sensor_object]['status'] = False

            for temperature_object, temperature_data in temperature_thresholds.items():
                structured_temperature_data = {k: v for k, v in temperature_data}
                if structured_object_data['class'] == 'Temp':
                    # Create a dict for the 'temperature' key
                    try:
                        environment_data['temperature'][sensor_object] = dict()
                    except KeyError:
                        environment_data['temperature'] = dict()
                        environment_data['temperature'][sensor_object] = dict()

                    environment_data['temperature'][sensor_object]['temperature'] = float(structured_object_data['temperature'])
                    # Set a default value (False) to the key is_critical and is_alert
                    environment_data['temperature'][sensor_object]['is_alert'] = False
                    environment_data['temperature'][sensor_object]['is_critical'] = False
                    # Check if the working temperature is equal to or higher than alerting threshold
                    if structured_temperature_data['red-alarm'] <= structured_object_data['temperature']:
                        environment_data['temperature'][sensor_object]['is_critical'] = True
                        environment_data['temperature'][sensor_object]['is_alert'] = True
                    elif structured_temperature_data['yellow-alarm'] <= structured_object_data['temperature']:
                        environment_data['temperature'][sensor_object]['is_alert'] = True

        for routing_engine_object, routing_engine_data in routing_engine.items():
            structured_routing_engine_data = {k: v for k, v in routing_engine_data}
            # Create dicts for 'cpu' and 'memory'.
            try:
                environment_data['cpu'] = dict()
                environment_data['cpu'][routing_engine_object] = dict()
                environment_data['memory'] = dict()
            except KeyError:
                environment_data['cpu'] = dict()
                environment_data['cpu'][routing_engine_object] = dict()
                environment_data['memory'] = dict()
            # Calculate the CPU usage by using the CPU idle value.
            environment_data['cpu'][routing_engine_object]['%usage'] = 100 - structured_routing_engine_data['cpu-idle']
            environment_data['memory']['available_ram'] = structured_routing_engine_data['memory-dram-size']
            # Junos gives us RAM in %, so calculation has to be made.
            # Sadly, bacause of this, results are not 100% accurate to the truth.
            environment_data['memory']['used_ram'] = (structured_routing_engine_data['memory-dram-size'] / 100 * structured_routing_engine_data['memory-buffer-utilization'])

        return environment_data

    # def get_bgp_neighbors(self):
    #
    #     # init result dict
    #     result = {}
    #
    #     instances = junos_views.junos_route_instance_table(self.device)
    #     instances.get()
    #
    #     for vrf in instances.keys():
    #         if not vrf.startswith('__'):
    #
    #             # init result dict for this vrf
    #             result[vrf] = {
    #                 'peers': {},
    #                 'router_id': None,
    #                 'local_as': None,
    #             }
    #
    #             # fetch sessions for vrf
    #             bgp = junos_views.junos_bgp_table(self.device)
    #             bgp.get(instance=vrf)
    #
    #             # assemble result dict
    #             bgp_result = {}
    #             [bgp_result.update({neigh:dict(bgp[neigh])}) for neigh in bgp.keys()]
    #             result[vrf]['peers'] = bgp_result
    #
    #     return result

    @staticmethod
    def _get_address_family(table):
        """
        Function to derive address family from a junos table name
        :params table: The name of the routing table
        :returns: address family
        """
        address_family_mapping = {
            'inet': 'ipv4',
            'inet6': 'ipv6'
        }
        family = table.split('.')[-2]
        return address_family_mapping[family]

    def _parse_route_stats(self, neighbor):
        data = {}
        if not neighbor['is_up']:
            pass
        elif isinstance(neighbor['tables'], list):
            for idx, table in enumerate(neighbor['tables']):
                family = self._get_address_family(table)
                data[family] = {}
                data[family]['received_prefixes'] = neighbor['received_prefixes'][idx]
                data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'][idx]
                data[family]['sent_prefixes'] = neighbor['sent_prefixes'][idx]
        else:
            family = self._get_address_family(neighbor['tables'])
            data[family] = {}
            data[family]['received_prefixes'] = neighbor['received_prefixes']
            data[family]['accepted_prefixes'] = neighbor['accepted_prefixes']
            data[family]['sent_prefixes'] = neighbor['sent_prefixes']
        return data

    @staticmethod
    def _parse_value(value):
        if isinstance(value, basestring):
            return unicode(value)
        elif value is None:
            return u''
        else:
            return value

    def get_bgp_neighbors(self):
        instances = junos_views.junos_route_instance_table(self.device)
        uptime_table = junos_views.junos_bgp_uptime_table(self.device)
        bgp_neighbors = junos_views.junos_bgp_table(self.device)
        keys =['local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id']
        bgp_neighbor_data = {}
        for instance, instance_data in instances.get().items():
            if instance.startswith('__'):
                # junos internal instances
                continue
            instance_name = "global" if instance == 'master' else instance
            bgp_neighbor_data[instance_name] = {'peers': {}}
            for neighbor, data in bgp_neighbors.get(instance=instance).items():
                neighbor_data = {k: v for k, v in data}
                peer_ip = neighbor.split('+')[0]
                if 'router_id' not in bgp_neighbor_data[instance_name]:
                    # we only need to set this once
                    bgp_neighbor_data[instance_name]['router_id'] = unicode(neighbor_data['local_id'])
                peer = {key:self._parse_value(value) for key, value in neighbor_data.iteritems() if key in keys}
                peer['address_family'] = self._parse_route_stats(neighbor_data)
                bgp_neighbor_data[instance_name]['peers'][peer_ip] = peer
            for neighbor, uptime in uptime_table.get(instance=instance).items():
                bgp_neighbor_data[instance_name]['peers'][neighbor]['uptime'] = uptime[0][1]
        for key in bgp_neighbor_data.keys():
            if not bgp_neighbor_data[key]['peers']:
                del bgp_neighbor_data[key]
        return bgp_neighbor_data

    def get_lldp_neighbors(self):
        lldp = junos_views.junos_lldp_table(self.device)
        lldp.get()

        result = lldp.items()

        neighbors = dict()
        for neigh in result:
            if neigh[0] not in neighbors.keys():
                neighbors[neigh[0]] = list()
            neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]})

        return neighbors
Ejemplo n.º 49
0
from jnpr.junos import Device
from jnpr.junos.utils.config import Config

#template variables are added to a dict or dictionary. A dict is simply a key/value store data structure
my_variables = {"hostname":"JNPRConfig-ez-set","enc_password":"******","ssh_root_login":"******"}

#now lets connect to the device, load the template, and commit the changes
#first we instantiate an instance of the device
junos_dev = Device(host='172.16.237.128', user='******', password='******' )
#We must bind an empty configuration to the device
junos_dev.bind(cu=Config)
#now we can connect to the device
junos_dev.open()
#lets go ahead and load the configuration. We are reading fromt he local directory and specifying the jnpr-config.conf file
#the file exension specifies the config type of config stored in the file
junos_dev.cu.load(template_path="./set-config.set",merge=True,template_vars=my_variables)
#commit and close the config
commit_result = junos_dev.cu.commit()
#Show that the commit worked True means it worked, false means it failed
print commit_result
#lastly we close the connection to the device
junos_dev.close()
Ejemplo n.º 50
0
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
r0 = Device(host='172.16.1.254', user='******', password='******').open()
r0.bind(cu=Config)
r0.cu
from lxml import etree
result = r0.cu.load(path='border1-template.set')
etree.dump(result)
Ejemplo n.º 51
0
import paramiko
import os, sys

from jnpr.junos import Device as Netconf

# local import
from uac import UAC

if len(sys.argv) < 2:
  print "you must provide a Junos target hostname"
  sys.exit(1)

# going to use paramiko SSHConfig to retrieve the port parameters for a given
# host.  Doing this because I tend to use jumphosts to get to devices behind
# firewalls/etc.  This is a pretty useful technique to illustrate:

junos_hostname = sys.argv[1]
config_file = os.path.join(os.getenv('HOME'),'.ssh/config')
ssh_config = paramiko.SSHConfig()
ssh_config.parse(open(config_file,'r'))
got_lkup = ssh_config.lookup( junos_hostname )

dev = Netconf(user='******',host=got_lkup['hostname'],port=got_lkup['port'])
dev.open()

dev.bind(uac=UAC)
dev.uac.get_users()

print "UAC users:"
print dev.uac.usernames
Ejemplo n.º 52
0
class TestDevice(unittest.TestCase):

    @patch('ncclient.manager.connect')
    def setUp(self, mock_connect):
        mock_connect.side_effect = self._mock_manager

        self.dev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.dev.open()

    @patch('ncclient.operations.session.CloseSession.request')
    def tearDown(self, mock_session):
        self.dev.close()

    def test_new_console_return(self):
        dev = Device(host='1.1.1.1', user='******', password='******',
                     port=23, gather_facts=False)
        self.assertTrue(isinstance(dev, Console))

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectAuthError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.AuthenticationError
        self.assertRaises(EzErrors.ConnectAuthError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectRefusedError(self, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError
        self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager):
        mock_manager.connect.side_effect = NcErrors.SSHError(
            "Could not open socket to 1.1.1.1:830")
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    @patch('jnpr.junos.device.datetime')
    def test_device_diff_err_message(self, mock_datetime, mock_manager):
        NcErrors.SSHError.message = 'why are you trying :)'
        mock_manager.connect.side_effect = NcErrors.SSHError
        from datetime import timedelta, datetime
        currenttime = datetime.now()
        mock_datetime.datetime.now.side_effect = [currenttime,
                                                  currenttime +
                                                  timedelta(minutes=4)]
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_ConnectUnknownHostError(self, mock_manager):
        import socket
        mock_manager.connect.side_effect = socket.gaierror
        self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open)

    @patch('jnpr.junos.device.netconf_ssh')
    def test_device_other_error(self, mock_manager):
        mock_manager.connect.side_effect = TypeError
        self.assertRaises(EzErrors.ConnectError, self.dev.open)

    def test_device_probe_error(self):
        mock_probe = MagicMock()
        mock_probe.return_value = None
        self.dev.probe = mock_probe

        def fn():
            self.dev.open(auto_probe=1)
        self.assertRaises(EzErrors.ProbeError, fn)

    def test_device_property_logfile_isinstance(self):
        mock = MagicMock()
        with patch(builtin_string + '.open', mock):
            if sys.version > '3':
                builtin_file = 'io.TextIOWrapper'
            else:
                builtin_file = builtin_string + '.file'
            with patch(builtin_file, MagicMock):
                handle = open('filename', 'r')
                self.dev.logfile = handle
                self.assertEqual(self.dev.logfile, handle)

    def test_device_host_mand_param(self):
        self.assertRaises(ValueError, Device, user='******',
                          password='******',
                          gather_facts=False)

    def test_device_property_logfile_close(self):
        self.dev._logfile = MagicMock()
        self.dev._logfile.close.return_value = 0
        self.dev.logfile = None
        self.assertFalse(self.dev._logfile)

    def test_device_property_logfile_exception(self):
        try:
            self.dev.logfile = True
        except Exception as ex:
            self.assertEqual(type(ex), ValueError)

    def test_device_master_is_master(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_backup(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = False
        localdev.facts._cache['RE_hw_mi'] = False
        localdev.facts._cache['current_re'] = ['re0']
        self.assertEqual(localdev.master, True)

    def test_device_master_is_multi_chassis_non_master1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_multi_chassis_non_master2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['lcc1-re0', 'member1-re0',
                                               'lcc1-master', 'member1-master',
                                               'member1']
        self.assertEqual(localdev.master, False)

    def test_device_master_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.master, None)

    def test_device_master_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['2RE'] = True
        localdev.facts._cache['current_re'] = ['foo', 'bar']
        self.assertEqual(localdev.master, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_master_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.master, None)

    def test_device_master_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.master = 'foo'

    def test_device_re_name_is_re0(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re0', 'backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'tapir',
                                                  're1': 'tapir1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_lcc_re1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['lcc1-re1', 'member1-re1',
                                               'lcc1-backup', 'member1-backup']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 'lcc1-re1')

    def test_device_re_name_is_re0_only(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['foo']
        localdev.facts._cache['hostname_info'] = {'re0': 'mj1'}
        self.assertEqual(localdev.re_name, 're0')

    def test_device_re_name_is_none1(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = None
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_is_none2(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        localdev.facts._cache['current_re'] = ['re1', 'master', 'node',
                                               'fwdd', 'member', 'pfem']
        localdev.facts._cache['hostname_info'] = None
        self.assertEqual(localdev.re_name, None)

    @patch('jnpr.junos.device.warnings')
    def test_device_re_name_is_old_facts(self, mock_warn):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          fact_style='old', gather_facts=False)
        mock_warn.assert_has_calls([call.warn('fact-style old will be removed '
                                              'in a future release.',
                                              RuntimeWarning)])
        self.assertEqual(localdev.re_name, None)

    def test_device_re_name_setter(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        with self.assertRaises(RuntimeError):
            localdev.re_name = 'foo'

    def test_device_repr(self):
        localdev = Device(host='1.1.1.1', user='******', password='******',
                          gather_facts=False)
        self.assertEqual(repr(localdev), 'Device(1.1.1.1)')

    def test_device_local(self):
        Device.ON_JUNOS = True
        localdev = Device()
        self.assertEqual(localdev._hostname, 'localhost')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('jnpr.junos.device.os')
    @patch(builtin_string + '.open')
    @patch('paramiko.config.SSHConfig.lookup')
    def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock):
        os_mock.path.exists.return_value = True
        self.dev._ssh_config = '/home/rsherman/.ssh/config'
        self.dev._sshconf_lkup()
        mock_paramiko.assert_called_once_with('1.1.1.1')

    @patch('os.getenv')
    def test_device__sshconf_lkup_path_not_exists(self, mock_env):
        mock_env.return_value = '/home/test'
        self.assertEqual(self.dev._sshconf_lkup(), None)

    @patch('os.getenv')
    def test_device__sshconf_lkup_home_not_defined(self, mock_env):
        mock_env.return_value = None
        self.assertEqual(self.dev._sshconf_lkup(), None)
        mock_env.assert_called_with('HOME')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open(self, mock_connect, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_cat.return_value = """

    domain jls.net

            """
            mock_connect.side_effect = self._mock_manager
            mock_execute.side_effect = self._mock_manager
            self.dev2 = Device(
                host='2.2.2.2',
                user='******',
                password='******')
            self.dev2.open()
            self.assertEqual(self.dev2.connected, True)

    @patch('jnpr.junos.Device.execute')
    def test_device_facts(self, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.return_value = """

    domain jls.net

            """
            self.dev.facts_refresh()
            self.dev.facts._cache['current_re'] = ['re0']
            assert self.dev.facts['version'] == facts['version']

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.factcache.warnings')
    def test_device_facts_error(self, mock_warnings, mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.dev.facts_refresh(warnings_on_failure=True)
            self.assertTrue(mock_warnings.warn.called)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_facts_error_exception_on_error(self, mock_warnings,
                                                   mock_execute):
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_old_style_facts_error_exception_on_error(self,
                                                             mock_warnings,
                                                             mock_execute):
        self.dev._fact_style = 'old'
        with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat:
            mock_execute.side_effect = self._mock_manager
            mock_cat.side_effect = IOError('File cant be handled')
            self.assertRaises(IOError, self.dev.facts_refresh,
                              exception_on_failure=True)

    def test_device_facts_refresh_unknown_fact_style(self):
        self.dev._fact_style = 'bad'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh()

    def test_device_facts_refresh_old_fact_style_with_keys(self):
        self.dev._fact_style = 'old'
        with self.assertRaises(RuntimeError):
            self.dev.facts_refresh(keys='domain')

    def test_device_hostname(self):
        self.assertEqual(self.dev.hostname, '1.1.1.1')

    def test_device_user(self):
        self.assertEqual(self.dev.user, 'test')

    def test_device_get_password(self):
        self.assertEqual(self.dev.password, None)

    def test_device_set_password(self):
        self.dev.password = '******'
        self.assertEqual(self.dev._auth_password, 'secret')

    def test_device_get_timeout(self):
        self.assertEqual(self.dev.timeout, 30)

    def test_device_set_timeout(self):
        self.dev.timeout = 10
        self.assertEqual(self.dev.timeout, 10)

    def test_device_set_timeout_string(self):
        self.dev.timeout = '10'
        self.assertEqual(self.dev.timeout, 10)

    def test_device_set_timeout_invalid_string_value(self):
        with self.assertRaises(RuntimeError):
            self.dev.timeout = 'foo'

    def test_device_set_timeout_invalid_type(self):
        with self.assertRaises(RuntimeError):
            self.dev.timeout = [1,2,3,4]

    def test_device_manages(self):
        self.assertEqual(self.dev.manages, [],
                         'By default manages will be empty list')

    @patch('ncclient.manager.connect')
    @patch('jnpr.junos.Device.execute')
    def test_device_open_normalize(self, mock_connect, mock_execute):
        mock_connect.side_effect = self._mock_manager
        self.dev2 = Device(host='2.2.2.2', user='******', password='******')
        self.dev2.open(gather_facts=False, normalize=True)
        self.assertEqual(self.dev2.transform, self.dev2._norm_transform)

    def test_device_set_facts_exception(self):
        try:
            self.dev.facts = 'test'
        except RuntimeError as ex:
            self.assertEqual(RuntimeError, type(ex))

    def test_device_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            ofacts = self.dev.ofacts

    def test_device_set_ofacts_exception(self):
        with self.assertRaises(RuntimeError):
            self.dev.ofacts = False

    @patch('jnpr.junos.Device.execute')
    def test_device_cli(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show cli directory',
                                      warning=False).tag, 'cli')

    @patch('jnpr.junos.device.json.loads')
    def test_device_rpc_json_ex(self, mock_json_loads):
        self.dev.facts = facts
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        ex = ValueError('Extra data ')
        ex.message = 'Extra data '  # for py3 as we dont have message thr
        mock_json_loads.side_effect = [
            ex,
            self._mock_manager(etree.fromstring(
                '<get-route-information format="json"/>'))]
        self.dev.rpc.get_route_information({'format': 'json'})
        self.assertEqual(mock_json_loads.call_count, 2)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('show system uptime')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show system uptime | match foo | count')
        self.assertEqual("rpc.get_system_uptime_information()", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_complex(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string(
            'show interfaces ge-0/0/0.0 routing-instance all media')
        self.assertEqual("rpc.get_interface_information("
                         "routing_instance='all', media=True, "
                         "interface_name='ge-0/0/0.0')", data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_to_rpc_string_invalid(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli_to_rpc_string('foo')
        self.assertEqual(None, data)

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_format_json(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interface terse',
                            warning=False, format='json')
        self.assertEqual(type(data), dict)
        self.assertEqual(data['interface-information'][0]
                         ['physical-interface'][0]['oper-status'][0]['data'],
                         'up')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_conf_info(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration',
                                                   warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_output(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertTrue('Alarm' in self.dev.cli('show system alarms',
                                                warning=False))

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.device.warnings')
    def test_device_cli_output_warning(self, mock_warnings, mock_execute):
        mock_execute.side_effect = self._mock_manager
        data = self.dev.cli('show interfaces ge-0/0/0.0 routing-instance '
                            'all media', format='xml')
        ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/'
                           'address-family[address-family-name="inet"]/'
                           'interface-address/ifa-local')
        self.assertTrue('192.168.100.1' in ip)
        self.assertTrue(mock_warnings.warn.called)
        rpc_string = "rpc.get_interface_information(routing_instance='all', "\
                     "media=True, interface_name='ge-0/0/0.0')"
        self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0])

    def test_device_cli_blank_output(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual('', self.dev.cli('show configuration interfaces',
                                          warning=False))

    def test_device_cli_rpc_reply_with_message(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(
            '\nprotocol: operation-failed\nerror: device asdf not found\n',
            self.dev.cli('show interfaces terse asdf',
                         warning=False))

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(self.dev.cli('show system uptime| display xml rpc',
                                      warning=False)
                         .tag, 'get-system-uptime-information')

    def test_device_cli_exception(self):
        self.dev.rpc.cli = MagicMock(side_effect=AttributeError)
        val = self.dev.cli('show version')
        self.assertEqual(val, 'invalid command: show version')

    @patch('jnpr.junos.Device.execute')
    def test_device_cli_rpc_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        val = self.dev.cli('foo')
        self.assertEqual(val, 'invalid command: foo: RpcError')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show system uptime').tag,
            'get-system-uptime-information')

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_rpc_text(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertIn(
            '<get-system-uptime-information>',
            self.dev.display_xml_rpc(
                'show system uptime',
                format='text'))

    @patch('jnpr.junos.Device.execute')
    def test_device_display_xml_exception(self, mock_execute):
        mock_execute.side_effect = self._mock_manager
        self.assertEqual(
            self.dev.display_xml_rpc('show foo'),
            'invalid command: show foo| display xml rpc')

    def test_device_execute(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>').tag,
                         'directory-list')

    def test_device_execute_topy(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertEqual(self.dev.execute('<get-system-core-dumps/>',
                                          to_py=self._do_nothing), 'Nothing')

# This test is for the commented out rpc-error code
#     def test_device_execute_exception(self):
#         self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
#         self.assertRaises(RpcError, self.dev.execute,
#                           '<load-configuration-error/>')

    @patch('jnpr.junos.device.warnings')
    def test_device_execute_unknown_exception(self, mock_warnings):
        class MyException(Exception):
            pass
        self.dev._conn.rpc = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.dev.execute,
                          '<get-software-information/>')

    def test_device_execute_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(RpcError, self.dev.rpc.get_rpc_error)

    def test_device_execute_permission_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertRaises(
            EzErrors.PermissionError,
            self.dev.rpc.get_permission_denied)

    def test_device_execute_index_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        self.assertTrue(self.dev.rpc.get_index_error())

    def test_device_execute_ValueError(self):
        self.assertRaises(ValueError, self.dev.execute, None)

    def test_device_execute_unopened(self):
        self.dev.connected = False
        self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None)

    def test_device_execute_timeout(self):
        self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError)
        self.assertRaises(
            EzErrors.RpcTimeoutError,
            self.dev.rpc.get_rpc_timeout)

    def test_device_execute_closed(self):
        self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError)
        self.assertRaises(
            EzErrors.ConnectClosedError,
            self.dev.rpc.get_rpc_close)
        self.assertFalse(self.dev.connected)

    def test_device_rpcmeta(self):
        self.assertEqual(self.dev.rpc.get_software_information.__doc__,
                         'get-software-information')

    def test_device_probe_timeout_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertFalse(self.dev.probe(0))

    def test_device_probe_timeout_gt_zero(self):
        with patch('jnpr.junos.device.socket'):
            self.assertTrue(self.dev.probe(1),
                            'probe fn is not working for'
                            ' timeout greater than zero')

    def test_device_probe_timeout_exception(self):
        with patch('jnpr.junos.device.socket') as mock_socket:
            with patch('jnpr.junos.device.time.sleep') as mock_time:
                mock_socket.socket.return_value.close.side_effect \
                    = RuntimeError
                mock_time.return_value = None
                self.assertFalse(self.dev.probe(.01))

    def test_device_bind_varg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.__name__ = 'magic_mock'
        self.dev.bind(mock)
        self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock')

    def test_device_bind_kvarg(self):
        self.dev.bind()
        mock = MagicMock()
        mock.return_value = 'Test'
        self.dev.bind(kw=mock)
        self.assertEqual(self.dev.kw, 'Test')

    def test_device_bind_varg_exception(self):
        def varg():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for *args
            self.dev.bind(mock)
            self.dev.bind(mock)
        self.assertRaises(ValueError, varg)

    def test_device_bind_kvarg_exception(self):
        def kve():
            self.dev.bind()
            mock = MagicMock()
            mock.__name__ = 'magic mock'
            # for **kwargs
            self.dev.bind(kw=mock)
            self.dev.bind(kw=mock)
        self.assertRaises(ValueError, kve)

    def test_device_template(self):
        # Try to load the template relative to module base
        try:
            template = self.dev.Template(
                'tests/unit/templates/config-example.xml')
        except:
            # Try to load the template relative to test base
            try:
                template = self.dev.Template('templates/config-example.xml')
            except:
                raise
        self.assertEqual(template.render({'host_name': '1',
                                          'domain_name': '2'}),
                         'system {\n  host-name 1;\n  domain-name 2;\n}')

    def test_device_close(self):
        def close_conn():
            self.dev.connected = False
        self.dev.close = MagicMock(name='close')
        self.dev.close.side_effect = close_conn
        self.dev.close()
        self.assertEqual(self.dev.connected, False)

    @patch('ncclient.manager.connect')
    def test_device_context_manager(self, mock_connect):
        mock_connect.side_effect = self._mock_manager
        try:
            with Device(host='3.3.3.3', user='******',
                        password='******', gather_facts=False) as dev:
                self.assertTrue(dev.connected)
                dev._conn = MagicMock(name='_conn')
                dev._conn.connected = True

                def close_conn():
                    dev.connected = False
                dev.close = MagicMock(name='close')
                dev.close.side_effect = close_conn
                raise RpcError
        except Exception as e:
            self.assertIsInstance(e, RpcError)
        self.assertFalse(dev.connected)

    def _read_file(self, fname):
        from ncclient.xml_ import NCElement

        fpath = os.path.join(os.path.dirname(__file__),
                             'rpc-reply', fname)
        with open(fpath) as fp:
            foo = fp.read()

            if fname == 'get-rpc-error.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif fname == 'get-permission-denied.xml':
                # Raise ncclient exception for error
                raise RPCError(etree.XML(foo))
            elif (fname == 'get-index-error.xml' or
                    fname == 'get-system-core-dumps.xml' or
                    fname == 'load-configuration-error.xml' or
                    fname == 'show-configuration-interfaces.xml' or
                  fname == 'show-interfaces-terse-asdf.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            elif (fname == 'show-configuration.xml' or
                  fname == 'show-system-alarms.xml'):
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc
            elif fname == 'show-interface-terse.json':
                rpc_reply = json.loads(foo)
            elif fname == 'get-route-information.json':
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())
            else:
                rpc_reply = NCElement(foo, self.dev._conn._device_handler
                                      .transform_reply())._NCElement__doc[0]
        return rpc_reply

    def _mock_manager(self, *args, **kwargs):
        if kwargs and 'normalize' not in kwargs:
            device_params = kwargs['device_params']
            device_handler = make_device_handler(device_params)
            session = SSHSession(device_handler)
            return Manager(session, device_handler)
        elif args:
            if args[0].tag == 'command':
                if args[0].text == 'show cli directory':
                    return self._read_file('show-cli-directory.xml')
                if args[0].text == 'show interface terse':
                    return self._read_file('show-interface-terse.json')
                elif args[0].text == 'show configuration':
                    return self._read_file('show-configuration.xml')
                elif args[0].text == 'show system alarms':
                    return self._read_file('show-system-alarms.xml')
                elif args[0].text == 'show system uptime| display xml rpc':
                    return self._read_file('show-system-uptime-rpc.xml')
                elif args[0].text == 'show configuration interfaces':
                    return self._read_file('show-configuration-interfaces.xml')
                elif args[0].text == 'show interfaces terse asdf':
                    return self._read_file('show-interfaces-terse-asdf.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media':
                    return self._read_file(
                        'show-interfaces-routing-instance-media.xml')
                elif args[0].text == 'show interfaces ge-0/0/0.0 ' \
                                     'routing-instance all media| display ' \
                                     'xml rpc':
                    return self._read_file(
                        'show-interfaces-routing-instance-media-rpc.xml')
                else:
                    raise RpcError

            else:
                if args[0].attrib.get('format') == 'json':
                    return self._read_file(args[0].tag + '.json')
                return self._read_file(args[0].tag + '.xml')

    def _do_nothing(self, *args, **kwargs):
        return 'Nothing'
Ejemplo n.º 53
0
def main():
    hosts = config.get('hosts')

    for host in hosts:
        dev = Device(host=host, user=user, password=password)

        # Open Connection
        try:
            dev.open()
        except Exception as err:
            print("Cannot connect to device: {}".format(err))
            return

        dev.bind(cu=Config)

        # Lock the configuration, load changes, commit
        print("Locking the configuration on: {}".format(host))
        try:
            dev.cu.lock()
        except LockError:
            print("Error: Unable to lock configuration on: {}".format(host))
            dev.close()
            return

        print("Loading configuration changes on: {}".format(host))
        try:
            # If your devices don't already have NTP configured, comment out
            # the next 4 lines
            set_commands = """
            delete system ntp
            """
            dev.cu.load(set_commands, format='set')
            dev.cu.load(template_path=template,
                        template_vars=config,
                        format='text')
        except ValueError as err:
            print(err.message)

        except Exception as err:
            if err.rsp.find('.//ok') is None:
                rpc_msg = err.rsp.findtext('.//error-message')
                print("Unable to load config changes: {}".format(rpc_msg))

            print("Unlocking the configuration")
            try:
                dev.cu.unlock()
            except UnlockError:
                print("Error: Unable to unlock configuration")
            dev.close()
            return

        print("Committing the configuration on: {}".format(host))
        try:
            dev.cu.commit()
            # print dev.cu.diff()
        except CommitError:
            print("Error: Unable to commit configuration")
            print("Unlocking the configuration")
            try:
                dev.cu.unlock()
            except UnlockError:
                print("Error: Unable to unlock configuration")
            dev.close()
            return

        print("Unlocking the configuration")
        try:
            dev.cu.unlock()
        except UnlockError:
            print("Error: Unable to unlock configuration")

        dev.close()
Ejemplo n.º 54
0
from pprint import pprint as pp 
from lxml import etree

# for the example ...
from jnpr.junos import Device as Junos
from jnpr.junos.cfg.srx.nat import NatStaticRuleSet
from jnpr.junos.utils.config import Config

# create a junos device and open a connection

jdev = Junos(user='******', password='******', host='vsrx_cyan')
jdev.open()

# now metabind some resource managers

jdev.bind( cu=Config )
jdev.bind( nat=NatStaticRuleSet )

# create a static NAT ruleset called 'outside' and map it on the from-zone "OUTSIDE-DC-STD1"

nat = jdev.nat["outside"]
nat(zone_from="OUTSIDE-DC-ST1")
nat.write()

# now create a rule within that ruleset called "foo" to static NAT 198.18.11.5 to 10.0.0.4
# for port 80.  Also enable proxy-arp on interface reth0.213"

r = nat.rule["foo"]
r(match_dst_addr="198.18.11.5", match_dst_port="80", nat_addr="10.0.0.4", nat_port="80")
r(proxy_interface="reth0.213")
r.write()
Ejemplo n.º 55
0
from lxml import etree

# for the example ...
from jnpr.junos import Device as Junos
from jnpr.junos.cfg.srx.nat import NatSrcPool, NatSrcRuleSet
from jnpr.junos.utils.config import Config

# create a junos device and open a connection

login = dict(user='******', host='vsrx_cyan', password='******')
jdev = Junos(**login)
jdev.open()

# now metabind some resource managers

jdev.bind(cu=Config)
jdev.bind(np=NatSrcPool)
jdev.bind(nr=NatSrcRuleSet)

# create a NAT source pool called 'POOL-A' with
# an address range from 198.18.0.1/32 to 198.18.0.10/32
# here showing the technique to change property values
# by making a "call" into the resource

r = jdev.np["POOL-A"]
r(addr_from="198.18.0.1", addr_to="198.18.0.10")
r.write()

# create a NAT source ruleset called "OUTBOUND_NAT"
# for a given zone-context matching on all traffic
# using HTTP (port-80), let's assume this is a compelely
Ejemplo n.º 56
0
class JunOSDriver(NetworkDriver):
    def __init__(self, hostname, username, password):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.device = Device(hostname, user=username, password=password)
        self.config_replace = False

    def open(self):
        self.device.open()
        self.device.timeout = 60
        self.device.bind(cu=Config)
        self.device.cu.lock()

    def close(self):
        self.device.cu.unlock()
        self.device.close()

    def _load_candidate(self, filename, config, overwrite):
        if filename is None:
            configuration = config
        else:
            with open(filename) as f:
                configuration = f.read()

        try:
            self.device.cu.load(configuration,
                                format='text',
                                overwrite=overwrite)
        except ConfigLoadError as e:
            if self.config_replace:
                raise ReplaceConfigException(e.message)
            else:
                raise MergeConfigException(e.message)

    def load_replace_candidate(self, filename=None, config=None):
        self.config_replace = True
        self._load_candidate(filename, config, True)

    def load_merge_candidate(self, filename=None, config=None):
        self.config_replace = False
        self._load_candidate(filename, config, False)

    def compare_config(self):
        diff = self.device.cu.diff()

        if diff is None:
            return ''
        else:
            return diff.strip()

    def commit_config(self):
        self.device.cu.commit()

    def discard_config(self):
        self.device.cu.rollback(rb_id=0)

    def rollback(self):
        self.device.cu.rollback(rb_id=1)
        self.commit_config()

    def get_facts(self):

        output = self.device.facts

        uptime = 0
        if 'RE0' in output:
            uptime = output['RE0']['up_time']

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()
        interface_list = interfaces.keys()

        return {
            'vendor': u'Juniper',
            'model': unicode(output['model']),
            'serial_number': unicode(output['serialnumber']),
            'os_version': unicode(output['version']),
            'hostname': unicode(output['hostname']),
            'fqdn': unicode(output['fqdn']),
            'uptime': string_parsers.convert_uptime_string_seconds(uptime),
            'interface_list': interface_list
        }

    def get_interfaces(self):

        # init result dict
        result = {}

        interfaces = junos_views.junos_iface_table(self.device)
        interfaces.get()

        # convert all the tuples to our pre-defined dict structure
        for iface in interfaces.keys():
            result[iface] = {
                'is_up': interfaces[iface]['is_up'],
                'is_enabled': interfaces[iface]['is_enabled'],
                'description': interfaces[iface]['description'] or u'',
                'last_flapped': interfaces[iface]['last_flapped'] or -1,
                'mac_address': unicode(interfaces[iface]['mac_address'])
            }
            result[iface]['last_flapped'] = float(
                result[iface]['last_flapped'])

            match = re.search(r'\d+', interfaces[iface]['speed'] or '')
            if match is not None:
                result[iface]['speed'] = int(match.group(0))
            else:
                result[iface]['speed'] = -1

        return result

    # def get_bgp_neighbors(self):
    #
    #     # init result dict
    #     result = {}
    #
    #     instances = junos_views.junos_route_instance_table(self.device)
    #     instances.get()
    #
    #     for vrf in instances.keys():
    #         if not vrf.startswith('__'):
    #
    #             # init result dict for this vrf
    #             result[vrf] = {
    #                 'peers': {},
    #                 'router_id': None,
    #                 'local_as': None,
    #             }
    #
    #             # fetch sessions for vrf
    #             bgp = junos_views.junos_bgp_table(self.device)
    #             bgp.get(instance=vrf)
    #
    #             # assemble result dict
    #             bgp_result = {}
    #             [bgp_result.update({neigh:dict(bgp[neigh])}) for neigh in bgp.keys()]
    #             result[vrf]['peers'] = bgp_result
    #
    #     return result

    def get_lldp_neighbors(self):
        lldp = junos_views.junos_lldp_table(self.device)
        lldp.get()

        result = lldp.items()

        neighbors = dict()
        for neigh in result:
            if neigh[0] not in neighbors.keys():
                neighbors[neigh[0]] = list()
            neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]})

        return neighbors
Ejemplo n.º 57
0
def main():
    dev = Device(host=host)

    # open a connection with the device and start a NETCONF session
    try:
        dev.open()
    except Exception as err:
        print "Cannot connect to device:", err
        return

    dev.bind( cu=Config )

    # Lock the configuration, load configuration changes, and commit
    print "Locking the configuration"
    try:
        dev.cu.lock()
    except LockError:
        print "Error: Unable to lock configuration"
        dev.close()
        return

    print "Loading configuration changes"
    try:
        dev.cu.load(path=conf_file, merge=True)
    except ValueError as err:
        print err.message

    except Exception as err:
        if err.rsp.find('.//ok') is None:
            rpc_msg = err.rsp.findtext('.//error-message')
            print "Unable to load configuration changes: ", rpc_msg

        print "Unlocking the configuration"
        try:
                dev.cu.unlock()
        except UnlockError:
                print "Error: Unable to unlock configuration"
        dev.close()
        return

    print "Committing the configuration"
    try:
        dev.cu.commit()
    except CommitError:
        print "Error: Unable to commit configuration"
        print "Unlocking the configuration"
        try:
            dev.cu.unlock()
        except UnlockError:
            print "Error: Unable to unlock configuration"
        dev.close()
        return

    print "Unlocking the configuration"
    try:
         dev.cu.unlock()
    except UnlockError:
         print "Error: Unable to unlock configuration"


    # End the NETCONF session and close the connection
    dev.close()
Ejemplo n.º 58
0
import pdb
from pprint import pprint as pp 
from lxml import etree
from lxml.builder import E 

# for the example ...
from jnpr.junos import Device 
from jnpr.junos.utils import Config

# create a junos device and open a connection

jdev = Device('jnpr-dc-fw')
jdev.open()

jdev.bind( cu=Config )

def show_diff_and_rollback():
  # dump the diff:
  print jdev.cu.diff()
  # [edit system]
  # -  host-name jnpr-dc-fw;
  # +  host-name jeremy;
  # +  domain-name jeremy.com;

  print "Rolling back...."
  jdev.cu.rollback()

set_commands = """
set system host-name jeremy
set system domain-name jeremy.com
"""
Ejemplo n.º 59
0
    show_help()

try:
    book_name = sys.argv[1]
    find_addr = sys.argv[2]
except:
    die("You must specify the ip-addr to locate")


jdev = Junos(user='******', host='vsrx_x46', password='******')
jdev.open()

# meta-toolbox the config-utils package onto this object,
# this gives us access to: jdev.ez.cu.<functions>

jdev.bind(ab=SharedAddrBook)

book = jdev.ab[book_name]
if not book.exists:
    die("Book %s does not exist on this device!" % book_name)


def do_find_addr(find_addr):
    print "Searching for address: " + find_addr
    f = AddrBookFinder(book)
    r = f.find(find_addr)

    print "\nAll items:"
    pp(r.items)

    print "\nJust matching address items:"