示例#1
0
def backup_config(host, user, password, port):
    cisco_device = {
        'device_type': 'cisco_ios',
        'ip': host,
        'username': str(user),
        'password': str(password),
        'port': port,
        'secret': str(password),
        'verbose': True,
    }
    try:
        net_connect = ConnectHandler(**cisco_device)
        output = net_connect.send_command("show configuration", delay_factor=2)
        net_connect.exit_enable_mode()
        filename = host + '--' + '{0:%Y-%m-%d-%H-%M-%S}'.format(
            datetime.datetime.now()) + '.txt'
        f = open(backup_dir + host + '/' + filename, 'w')
        f.write(output)
        f.close()
    except:
        net_connect = ConnectHandler(**cisco_device)
        net_connect.enable()
        output = net_connect.send_command("show running-config")
        net_connect.exit_enable_mode()
        filename = host + '--' + '{0:%Y-%m-%d-%H-%M-%S}'.format(
            datetime.datetime.now()) + '.txt'
        f = open(backup_dir + host + '/' + filename, 'w')
        f.write(output)
        f.close()
        f.write(output)
        f.close()
示例#2
0
def detect_epc_tap_capabilities(host, user, password):
    #USE ONLY ON YOUR OWN DEVICES
    #this allows you to check for tapping capabillities
    cisco_device = {
        'device_type': 'cisco_ios',
        'ip': host,
        'username': str(user),
        'password': str(password),
        'port': 22,  # optional, defaults to 22
        'secret': str(password),  # optional, defaults to ''
        'verbose': True,  # optional, defaults to False
    }
    try:
        net_connect = ConnectHandler(**cisco_device)
        output = net_connect.send_config_set("do monitor capture buffer ?")

        if "% Incomplete command." in output:
            print(output)
            print(
                "Target:" + host +
                " is Vulnerable To EPC Tapping See Mimosa Framework for POC\n")
            net_connect.exit_enable_mode()
            net_connect.disconnect()
            return True

    except:
        return False
示例#3
0
def execute(opts, net_cmd, net_config, device_commit, use_textfsm):
    """
    This function setups up a netmiko connection and performs the different commands.
    The results are returned in a json document
    :param opts:
    :param net_cmd:
    :param net_config:
    :param device_commit: used with net_config cmds
    :param use_textfsm: used with net_cmd to specify the results should be formatted through TextFSM
    :return: json results such as:
      {
        'status': 'success'|'failure',
        'reason': xx,
        'send_command': xx,
        'send_result': xx,
        'config_command': xx,
        'config_result': xx
      }
    """
    result = {}
    connection = None
    try:
        # if secret is specified, use enable_mode
        bEnable_mode = len(opts.get('secret', '')) > 0

        connection = ConnectHandler(**opts)

        if bEnable_mode:
            connection.enable()

        # standard commands to execute
        if net_cmd:
            result['send_command'] = net_cmd
            send_result = connection.send_command(net_cmd,
                                                  use_textfsm=use_textfsm)
            result['send_result'] = send_result

        # configuration commands to execute
        if net_config:
            result['config_command'] = net_config
            config_result = connection.send_config_set(net_config.split("\n"))
            result['config_result'] = config_result
            if device_commit:
                connection.commit()

        result['status'] = 'success'
    except Exception as err:
        result['status'] = 'failure'
        result['reason'] = str(err)

    finally:
        if connection:
            if bEnable_mode:
                connection.exit_enable_mode()

            connection.disconnect()

    return result
示例#4
0
def get_info(device, username, password):
    dev_config = 'none'
    try:
        net_connect = ConnectHandler(device_type='cisco_ios',
                                     ip=device,
                                     username=username,
                                     password=password,
                                     secret=password)
        net_connect.enable()
        net_connect.send_command('terminal length 0')
        dev_config = net_connect.send_command('show run')
        net_connect.exit_enable_mode()
        net_connect.disconnect()
        return dev_config
    except:
        with open("error_devices.txt", '+a') as errlog:
            errlog.write("error connecting to " + device + "\n")
        return dev_config
示例#5
0
def ssh_establisher(host, user, password):
    #USE ONLY ON YOUR OWN DEVICES
    #THIS ALLWOS YOU TO PATCH THE SMI VECTOR
    cisco_device = {
        'device_type': 'cisco_ios',
        'ip': host,
        'username': str(user),
        'password': str(password),
        'port': 22,  # optional, defaults to 22
        'secret': str(password),  # optional, defaults to ''
        'verbose': True,  # optional, defaults to False
    }
    try:
        net_connect = ConnectHandler(**cisco_device)
        #net_connect.find_prompt()
        output = net_connect.send_config_set("no vstack")
        if output:
            print(output)
        net_connect.exit_enable_mode()
        net_connect.disconnect()
        return output.split()
    except:
        pass
示例#6
0
 #Definindo Connect Handler
 router_connect=ConnectHandler(device_type=router['so'],ip=router['ip'],username=router['user'],password=router['pass'],secret=router['secret'],timeout=10)
 #Se o roteador eh ios, mudo para enable 
 if router['so'] == 'cisco_ios' :
  router_connect.enable()
 #Envio o comando 
 output=router_connect.send_command('sh version')  
 #Crio o arquivo e armazeno o resultado
 arquivosaida=router['ip'] + '_show_version.txt'
 with open(arquivosaida,'w') as fh:
  fh.write(output)
 #Configurando os roteadores e imprime a saida da configuracao
 output=router_connect.send_config_set(router['configure'])
 print(output)
 #Saio do enable se o roteador eh ios
 if router['so'] == 'cisco_ios' :
  output=router_connect.send_command('wr')
  print(output)
  #Saio do modo enable
  router_connect.exit_enable_mode()
 else:
  # Se o roteador eh Juniper mando um commit
  output=router_connect.commit(and_quit=True)
  print(output)

 #Fecho a conexao
 router_connect.disconnect()
  


    'password': '******',
    'secret': 'enablesecret',
}

try:
    net_connect = ConnectHandler(**cisco_asa)
except:
    print >> sys.stderr, "Unable to connec to ASA."
    sys.exit(1)

net_connect.enable()

backup_command = "backup location ftp:"
result = net_connect.send_command_timing(backup_command)

ftp_url = 'ftp://*****:*****@192.168.100.100/' + backup_filename

if 'Press return to continue or enter a backup location' in result:
    result += net_connect.send_command_timing(ftp_url)

net_connect.exit_enable_mode()
net_connect.disconnect()

file_path = ftp_location + backup_filename

while not os.path.exists(file_path):
    time.sleep(10)

if os.path.isfile(file_path):
    shutil.move(file_path, backup_location)
示例#8
0
from getpass import getpass

# load the json file as a dictionary.
with open('vms.json') as f:
    data = json.load(f)

# Get pod information for connecting.
pod = input("Enter pod id: ")
podinfo = data['vms'][f"pod" + pod.lower()]
print(f"Connecting to pod {podinfo['id']} with the ip {podinfo['ip']}")
username = input("Username: "******"Password: "******"Secret (Most likely the same as your password): ")

# Make a connection handler with the information provided plus the json.
virtualmachine = {
    'device_type': 'linux',
    'host':   podinfo['ip'],
    'username': username,
    'password': password,
    'port': 22,
    'secret': secret
}
connection = ConnectHandler(**virtualmachine)

# Use the information to connect, run command, and print it out. Then close connection.
connection.enable()
output = connection.send_command('dpkg --get-selections python3')
print(output)
connection.exit_enable_mode()
示例#9
0
def main():

    try:
        hostname = raw_input("Enter remote host to test: ")
        username = raw_input("Enter remote username: "******"Enter remote host to test: ")
        username = input("Enter remote username: "******"username": username,
        "use_keys": True,
        "ip": hostname,
        "device_type": "ovs_linux",
        "key_file": "/home/{}/.ssh/test_rsa".format(username),
        "verbose": False,
    }

    net_connect = ConnectHandler(**linux_test)
    print()
    print(net_connect.find_prompt())

    # Test enable mode
    print()
    print("***** Testing enable mode *****")
    net_connect.enable()
    if net_connect.check_enable_mode():
        print("Success: in enable mode")
    else:
        print("Fail...")
    print(net_connect.find_prompt())

    net_connect.exit_enable_mode()
    print("Out of enable mode")
    print(net_connect.find_prompt())

    # Test config mode
    print()
    print("***** Testing config mode *****")
    net_connect.config_mode()
    if net_connect.check_config_mode():
        print("Success: in config mode")
    else:
        print("Fail...")
    print(net_connect.find_prompt())

    net_connect.exit_config_mode()
    print("Out of config mode")
    print(net_connect.find_prompt())

    # Test config mode (when already at root prompt)
    print()
    print("***** Testing config mode when already root *****")
    net_connect.enable()
    if net_connect.check_enable_mode():
        print("Success: in enable mode")
    else:
        print("Fail...")
    print(net_connect.find_prompt())
    print("Test config_mode while already at root prompt")
    net_connect.config_mode()
    if net_connect.check_config_mode():
        print("Success: still at root prompt")
    else:
        print("Fail...")
    net_connect.exit_config_mode()
    # Should do nothing
    net_connect.exit_enable_mode()
    print("Out of config/enable mode")
    print(net_connect.find_prompt())

    # Send config commands
    print()
    print("***** Testing send_config_set *****")
    print(net_connect.find_prompt())
    output = net_connect.send_config_set(["ls -al"])
    print(output)
    print()
示例#10
0
def main():

    try: 
        hostname = raw_input("Enter remote host to test: ")
        username = raw_input("Enter remote username: "******"Enter remote host to test: ")
        username = input("Enter remote username: "******"***** Testing enable mode *****")
    net_connect.enable()
    if net_connect.check_enable_mode():
        print("Success: in enable mode")
    else:
        print("Fail...")
    print(net_connect.find_prompt())

    net_connect.exit_enable_mode()
    print("Out of enable mode")
    print(net_connect.find_prompt())

    # Test config mode 
    print()
    print("***** Testing config mode *****")
    net_connect.config_mode()
    if net_connect.check_config_mode():
        print("Success: in config mode")
    else:
        print("Fail...")
    print(net_connect.find_prompt())

    net_connect.exit_config_mode()
    print("Out of config mode")
    print(net_connect.find_prompt())

    # Test config mode (when already at root prompt)
    print()
    print("***** Testing config mode when already root *****")
    net_connect.enable()
    if net_connect.check_enable_mode():
        print("Success: in enable mode")
    else:
        print("Fail...")
    print(net_connect.find_prompt())
    print("Test config_mode while already at root prompt")
    net_connect.config_mode()
    if net_connect.check_config_mode():
        print("Success: still at root prompt")
    else:
        print("Fail...")
    net_connect.exit_config_mode()
    # Should do nothing
    net_connect.exit_enable_mode()
    print("Out of config/enable mode")
    print(net_connect.find_prompt())

    # Send config commands
    print()
    print("***** Testing send_config_set *****")
    print(net_connect.find_prompt())
    output = net_connect.send_config_set(['ls -al'])
    print(output)
    print()
# Import the connect handler module
from netmiko import ConnectHandler
# Create a dictionary representing the device.
testrouter = {
'device_type': 'cisco_ios',
'ip':   '134.86.133.30',
'username': '******',
'password': '******',
'secret': 'cisco',
}
# Connect to the device
net_connect = ConnectHandler(**testrouter)
# Elevate to enable mode
net_connect.enable()
# Import all configured routes into a variable
output = net_connect.send_command('show run | include ip route')
# Print the results for the variable "output"
print output
# exit enable mode
net_connect.exit_enable_mode()
# close the ssh session
net_connect.disconnect()
# end of the program
# stored at /usr/bin/route_scrape
示例#12
0
class NetworkDeviceIOS(NetworkDevice):

    #---------------------------------------------------------------------------
    def __init__(self, name, ip, user='******', pw='cisco', secret=''):
        NetworkDevice.__init__(self, name, ip, user, pw)
        self.secret = secret
        self.device = {
            'device_type': 'cisco_ios',
            'ip': self.ip_address,
            'username': self.username,
            'password': self.password,
            'secret': self.secret,
            'port': 22,
        }
        self.session = None
        logger.info('devclass: created IOS device: %s %s', name, ip)

#---------------------------------------------------------------------------

    def connect(self):
        try:
            print('--- connecting IOS: telnet: ' + self.ip_address + ' for: ' +
                  self.username)
            self.session = ConnectHandler(**self.device)
            logger.info('devclass: successful login at: %s for user: %s',
                        self.ip_address, self.username)
            return self.session
        except Exception as err:
            logger.error('devclass: Erro no login at: %s for user: %s',
                         self.ip_address, self.username)
            print('Ocorreu um Erro: ' + str(err))
            raise Exception('Erro em devclass.connect')

#---------------------------------------------------------------------------

    def disconnect(self):
        if self.esta_connectado():
            print('--- disconnecting IOS: telnet: ' + self.ip_address +
                  ' for: ' + self.username)
            self.session.disconnect()
            logger.info('devclass: successful logoff at: %s for user: %s',
                        self.ip_address, self.username)
        else:
            logger.warn('devclass: --- Erro ao desconectar.')
            print("Não há sessão para desconectar!")

#---------------------------------------------------------------------------

    def get_interfaces(self):
        if self.esta_connectado():
            self.interfaces = self.session.send_command("show int status")
            logger.info(
                'devclass: successful get_interfaces at: %s for user: %s',
                self.ip_address, self.username)
            return self.interfaces
        else:
            logger.error(
                'devclass: Erro ao executar devclass.get_interfaces() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.get_interfaces() - Sessao nao estabelecida.'
            )
            return "Erro "
#---------------------------------------------------------------------------

    def get_int_connected(self):
        if self.esta_connectado():
            output = self.session.send_command("show int status | i cted")
            logger.info(
                'devclass: successful get_int_connected at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.get_int_connected() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.get_int_connected() - Sessao nao estabelecida.'
            )
            return "erro"

#---------------------------------------------------------------------------

    def do_wr(self):
        if self.esta_connectado():
            output = self.session.send_command('write memory')
            logger.info('devclass: successful do_wr at: %s for user: %s',
                        self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.do_wr() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.do_wr() - Sessao nao estabelecida.')
#---------------------------------------------------------------------------

    def config_mode(self):
        if self.esta_connectado():
            output = self.session.config_mode()
            logger.info(
                'devclass: successful config_mode() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.config_mode() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.config_mode() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def exit_config_mode(self):
        if self.esta_connectado():
            output = self.sessionc.exit_config_mode()
            logger.info(
                'devclass: successful exit_config_mode() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.exit_config_mode() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.exit_config_mode() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def check_config_mode(self):
        if self.esta_connectado():
            output = self.session.check_config_mode()
            logger.info(
                'devclass: successful check_config_mode() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.check_config_mode() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.check_config_mode() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def enable(self):
        if self.esta_connectado():
            output = self.session.enable()
            logger.info('devclass: successful enable() at: %s for user: %s',
                        self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.enable() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.enable() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def exit_enable_mode(self):
        if self.esta_connectado():
            output = self.session.exit_enable_mode()
            logger.info(
                'devclass: successful exit_enable_mode() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.exit_enable_mode() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.exit_enable_mode() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def find_prompt(self):
        if self.esta_connectado():
            output = self.session.find_prompt()
            logger.info(
                'devclass: successful find_prompt() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.find_prompt() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.find_prompt() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def send_command(self, arguments):
        if self.esta_connectado():
            output = self.session.send_command(arguments)
            logger.info(
                'devclass: successful send_command() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.send_command() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.send_command() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def send_config_set(self, arguments_list):
        if self.esta_connectado():
            output = self.session.send_config_set(arguments_list)
            logger.info(
                'devclass: successful send_config_set() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.send_config_set() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.send_config_set() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def send_config_from_file(self, file):
        if self.esta_connectado():
            output = self.session.send_config_from_file(file)
            logger.info(
                'devclass: successful send_config_from_file() at: %s for user: %s',
                self.ip_address, self.username)
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.send_config_from_file() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.send_config_from_file() - Sessao nao estabelecida.'
            )
#---------------------------------------------------------------------------

    def esta_connectado(self):
        if self.session != None:
            return True
        else:
            return False
#---------------------------------------------------------------------------

    def debug_devclass(self):
        filename_log = self.ip_address + '_.log'
        logging.basicConfig(filename=filename_log,
                            format='%(asctime)s - %(levelname)s - %(message)s',
                            level=logging.DEBUG)
        debugClass = logging.getLogger("netmiko")
#---------------------------------------------------------------------------

    def get_hostname(self):
        if self.esta_connectado():
            output = self.session.send_command("show conf | i hostname")
            logger.info(
                'devclass: successful get_hostname at: %s for user: %s',
                self.ip_address, self.username)
            hostname = (output.split())[1]
            return hostname
        else:
            logger.error(
                'devclass: Erro ao executar devclass.get_hostname() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.get_hostname() - Sessao nao estabelecida.'
            )
            return "Erro "
#---------------------------------------------------------------------------

    def get_nbem(self):
        if self.esta_connectado():
            output = self.session.send_command("show run | i chassis")
            logger.info('devclass: successful get_nbem at: %s for user: %s',
                        self.ip_address, self.username)
            output = (output.split())[2]
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.get_nbem() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.get_nbem() - Sessao nao estabelecida.'
            )

    #---------------------------------------------------------------------------
    def get_serial(self):
        if self.esta_connectado():
            output = self.session.send_command(
                "show version | i System [s,S]erial")
            logger.info('devclass: successful get_serial at: %s for user: %s',
                        self.ip_address, self.username)
            outputlines = output.splitlines()
            serial = []
            for line in outputlines:
                serial.append((line.split(": "))[1])
            return serial
        else:
            logger.error(
                'devclass: Erro ao executar devclass.get_serial() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.get_serial() - Sessao nao estabelecida.'
            )


#---------------------------------------------------------------------------
#retorna o MAC pelo IP

    def busca_mac(self, end_ip):
        if self.esta_connectado():
            output = self.session.send_command("show arp | i %s" % end_ip)
            logger.info('devclass: successful busca_mac at: %s for user: %s',
                        self.ip_address, self.username)
            #output = (output.split())[2]
            return output
        else:
            logger.error(
                'devclass: Erro ao executar devclass.busca_mac() - Sessão não estabelecida. at: %s for user: %s',
                self.ip_address, self.username)
            raise Exception(
                'Erro ao executar devclass.busca_mac() - Sessao nao estabelecida.'
            )

    #---------------------------------------------------------------------------
示例#13
0
class NetCom:
    def __init__(self, hostname, user, devtype, command):

        self.hostname = hostname
        self.user = user
        self.devtype = devtype
        self.passwd = getpass()
        try:
            self.conn = ConnectHandler(device_type=self.devtype,
                                       host=self.hostname,
                                       username=self.user,
                                       password=self.passwd,
                                       secret=self.passwd,
                                       ssh_config_file="~/.ssh/config")
        except (EOFError, SSHException, ProxyCommandFailure,
                NetMikoTimeoutException, Exception):
            print('SSH is not enabled for this device ' + self.hostname + '\n')
            sys.exit()
        self.outdict = {}
        self.multi_commands = []
        if command:
            self.command = command
        else:
            self.command = ''

    def __enter__(self):
        if self.command:
            self.netmiko_send_single()
        else:
            sys.exit('no commands entered')

    def __exit__(self, type, value, traceback):
        # make sure the ssh connection is closed.
        #print(self.outdict())
        self.conn.disconnect()

    def netmiko_close_conn(self):
        self.conn.disconnect()

    def netmiko_findp(self):
        # Check connection is still valid
        if self.conn.find_prompt():
            # print('#######SUCCESSFULL##########')
            return True
        else:
            # print('########FAILED##############')
            print('Connection failed to node: ' + host + '\n')
            return False

    def sanitise_input(self):
        # search the comm_list of any instances of bad commands i.e. conf t, set, delete etc returns bolean!
        sanitise_list = [
            'conf', 'set', 'delete', 'modify'
        ]  # add to list for additional commands to be excluded
        for line in sanitise_list:
            for com in self.multi_commands:
                if line in com:
                    return True
        return False

    def netmiko_send(self):
        # check connection is still valid
        print(self.conn)
        if self.netmiko_findp():
            if self.sanitise_input:
                output = []
                self.conn.enable()
                for item in self.multi_commands:
                    print('***Executing command: ' + item + '\n')
                    com_return = self.conn.send_command(item)
                    output.append(com_return)
                    print('***Success\n')
                self.outdict = dict(zip(com_list, output))
                self.conn.exit_enable_mode()

    def netmiko_send_single(self):
        #sends a single command and prints
        if self.netmiko_findp():
            print(self.conn.send_command(self.command))
示例#14
0
class CumulusDriver(NetworkDriver):
    """Napalm driver for Cumulus."""

    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
        """Constructor."""
        self.device = None
        self.hostname = hostname
        self.username = username
        self.password = password
        self.timeout = timeout
        self.loaded = False
        self.changed = False

        if optional_args is None:
            optional_args = {}

        # Netmiko possible arguments
        netmiko_argument_map = {
            "port": None,
            "verbose": False,
            "global_delay_factor": 1,
            "use_keys": False,
            "key_file": None,
            "ssh_strict": False,
            "system_host_keys": False,
            "alt_host_keys": False,
            "alt_key_file": "",
            "ssh_config_file": None,
            "secret": password,
            "allow_agent": False,
        }

        # Build dict of any optional Netmiko args
        self.netmiko_optional_args = {
            k: optional_args.get(k, v) for k, v in netmiko_argument_map.items()
        }
        self.port = optional_args.get("port", 22)
        self.sudo_pwd = optional_args.get("sudo_pwd", self.password)

    def open(self):
        try:
            self.device = ConnectHandler(
                device_type="linux",
                host=self.hostname,
                username=self.username,
                password=self.password,
                **self.netmiko_optional_args
            )
        except NetMikoTimeoutException:
            raise ConnectionException("Cannot connect to {}".format(self.hostname))

    def close(self):
        self.device.disconnect()

    def is_alive(self):
        """Returns a flag with the state of the SSH connection."""
        null = chr(0)
        if self.device is None:
            return {'is_alive': False}
        try:
            # Try sending ASCII null byte to maintain the connection alive
            self.device.write_channel(null)
            return {'is_alive': self.device.remote_conn.transport.is_active()}
        except (socket.error, EOFError):
            # If unable to send, we can tell for sure that the connection is unusable
            return {'is_alive': False}
        return {
            'is_alive': self.device.remote_conn.transport.is_active()
        }


    def load_merge_candidate(self, filename=None, config=None):
        if not filename and not config:
            raise MergeConfigException("filename or config param must be provided.")

        self.loaded = True

        if filename is not None:
            with open(filename, "r") as f:
                candidate = f.readlines()
        else:
            candidate = config

        if not isinstance(candidate, list):
            candidate = [candidate]

        candidate = [line for line in candidate if line]
        for command in candidate:
            output = self._send_command(command)
            if "error" in output or "not found" in output:
                raise MergeConfigException(
                    "Command '{0}' cannot be applied.".format(command)
                )

    def discard_config(self):
        if self.loaded:
            self._send_command("net abort")
            self.loaded = False

    def compare_config(self):
        if self.loaded:
            diff = self._send_command("net pending")
            return re.sub(r"\x1b\[\d+m", "", diff)
        return ""

    def commit_config(self, message=""):
        if self.loaded:
            self._send_command("net commit")
            self.changed = True
            self.loaded = False

    def rollback(self):
        if self.changed:
            self._send_command("net rollback last")
            self.changed = False

    def _send_command(self, command):
        if command.startswith("sudo"):
            self.device.enable()
        response = self.device.send_command(command)
        if command.startswith("sudo"):
            self.device.exit_enable_mode()
        return response

    def get_facts(self):
        facts = {}

        # Get "net show system" output.
        system = json.loads(self._send_command("net show system json"))

        facts = {
            "uptime": string_parsers.convert_uptime_string_seconds(system["uptime"]),
            "vendor": system["eeprom"]["tlv"]["Vendor Name"]["value"],
            "model": system["eeprom"]["tlv"]["Product Name"]["value"],
            "hostname": system["hostname"],
            "os_version": system["os-version"],
            "serial_number": system["eeprom"]["tlv"]["Serial Number"]["value"]
        }
        facts["fqdn"] = facts["hostname"]

        # Get "net show interface all json" output.
        interfaces = self._send_command("net show interface all json")
        # Handling bad send_command_timing return output.
        try:
            interfaces = json.loads(interfaces)
        except ValueError:
            interfaces = json.loads(
                self.device.send_command("net show interface all json")
            )

        facts["interface_list"] = string_parsers.sorted_nicely(interfaces.keys())
        return facts

    def get_arp_table(self, vrf=""):

        """
        TODO replace with ip neighbor command since arp is being deprecated
        'show arp' output example:
        Address                  HWtype  HWaddress           Flags Mask            Iface
        10.129.2.254             ether   00:50:56:97:af:b1   C                     eth0
        192.168.1.134                    (incomplete)                              eth1
        192.168.1.1              ether   00:50:56:ba:26:7f   C                     eth1
        10.129.2.97              ether   00:50:56:9f:64:09   C                     eth0
        192.168.1.3              ether   00:50:56:86:7b:06   C                     eth1
        """
        if vrf:
            raise NotImplementedError
        output = self._send_command("arp -n")
        output = output.split("\n")
        output = output[1:]
        arp_table = list()

        for line in output:
            line = line.split()
            if "incomplete" in line[1]:
                macaddr = "00:00:00:00:00:00"
            else:
                macaddr = line[2]

            arp_table.append(
                {"interface": line[-1], "mac": macaddr, "ip": line[0], "age": 0.0}
            )
        return arp_table

    def get_ntp_stats(self):
        """
        'ntpq -np' output example
             remote           refid      st t when poll reach   delay   offset  jitter
        ==============================================================================
         116.91.118.97   133.243.238.244  2 u   51   64  377    5.436  987971. 1694.82
         219.117.210.137 .GPS.            1 u   17   64  377   17.586  988068. 1652.00
         133.130.120.204 133.243.238.164  2 u   46   64  377    7.717  987996. 1669.77
        """

        output = self._send_command("ntpq -np")
        output = output.split("\n")[2:]
        ntp_stats = list()

        for ntp_info in output:
            if len(ntp_info) > 0:
                remote, refid, st, t, when, hostpoll, reachability, delay, offset, jitter = (
                    ntp_info.split()
                )

                # 'remote' contains '*' if the machine synchronized with NTP server
                synchronized = "*" in remote

                match = re.search(r"(\d+\.\d+\.\d+\.\d+)", remote)
                ip = match.group(1)

                when = when if when != "-" else 0

                ntp_stats.append(
                    {
                        "remote": ip,
                        "referenceid": refid,
                        "synchronized": bool(synchronized),
                        "stratum": int(st),
                        "type": t,
                        "when": when,
                        "hostpoll": int(hostpoll),
                        "reachability": int(reachability),
                        "delay": float(delay),
                        "offset": float(offset),
                        "jitter": float(jitter),
                    }
                )
        return ntp_stats

    def ping(
        self,
        destination,
        source=C.PING_SOURCE,
        ttl=C.PING_TTL,
        timeout=C.PING_TIMEOUT,
        size=C.PING_SIZE,
        count=C.PING_COUNT,
        vrf=C.PING_VRF,
    ):

        deadline = timeout * count

        command = "ping %s " % destination
        command += "-t %d " % int(ttl)
        command += "-w %d " % int(deadline)
        command += "-s %d " % int(size)
        command += "-c %d " % int(count)
        if source != "":
            command += "interface %s " % source

        ping_result = dict()
        output_ping = self._send_command(command)

        if "Unknown host" in output_ping:
            err = "Unknown host"
        else:
            err = ""

        if err != "":
            ping_result["error"] = err
        else:
            # 'packet_info' example:
            # ['5', 'packets', 'transmitted,' '5', 'received,' '0%', 'packet',
            # 'loss,', 'time', '3997ms']
            packet_info = output_ping.split("\n")

            if "transmitted" in packet_info[-2]:
                packet_info = packet_info[-2]
            else:
                packet_info = packet_info[-3]

            packet_info = [x.strip() for x in packet_info.split()]

            sent = int(packet_info[0])
            received = int(packet_info[3])
            lost = sent - received

            # 'rtt_info' example:
            # ["0.307/0.396/0.480/0.061"]
            rtt_info = output_ping.split("\n")

            if len(rtt_info[-1]) > 0:
                rtt_info = rtt_info[-1]
            else:
                rtt_info = rtt_info[-2]

            match = re.search(r"([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+)", rtt_info)

            if match is not None:
                rtt_min = float(match.group(1))
                rtt_avg = float(match.group(2))
                rtt_max = float(match.group(3))
                rtt_stddev = float(match.group(4))
            else:
                rtt_min = None
                rtt_avg = None
                rtt_max = None
                rtt_stddev = None

            ping_responses = list()
            response_info = output_ping.split("\n")

            for res in response_info:
                match_res = re.search(r"from\s([\d\.]+).*time=([\d\.]+)", res)
                if match_res is not None:
                    ping_responses.append(
                        {
                            "ip_address": match_res.group(1),
                            "rtt": float(match_res.group(2)),
                        }
                    )

            ping_result["success"] = dict()

            ping_result["success"] = {
                "probes_sent": sent,
                "packet_loss": lost,
                "rtt_min": rtt_min,
                "rtt_max": rtt_max,
                "rtt_avg": rtt_avg,
                "rtt_stddev": rtt_stddev,
                "results": ping_responses,
            }

            return ping_result

    def _get_interface_neighbors(self, neighbors_list):
        neighbors = []
        for neighbor in neighbors_list:
            temp = {}
            temp["hostname"] = neighbor["adj_hostname"]
            temp["port"] = neighbor["adj_port"]
            neighbors.append(temp)
        return neighbors

    def get_lldp_neighbors(self):
        """Cumulus get_lldp_neighbors."""
        lldp = {}
        command = "net show interface all json"

        try:
            intf_output = json.loads(self._send_command(command))
        except ValueError:
            intf_output = json.loads(self.device.send_command(command))

        for interface in intf_output:
            if intf_output[interface]["iface_obj"]["lldp"] is not None:
                lldp[interface] = self._get_interface_neighbors(
                    intf_output[interface]["iface_obj"]["lldp"]
                )
        return lldp

    def get_interfaces(self):
        def _convert_speed(speed):
            if speed.endswith("M") and speed.strip("M").isdigit():
                return int(speed.strip("M"))
            elif speed.endswith("G") and speed.strip("G").isdigit():
                return int(speed.strip("G")) * 1000
            return -1

        interfaces = {}
        # Get 'net show interface all json' output.
        output = self._send_command("net show interface all json")
        # Handling bad send_command_timing return output.
        try:
            output_json = json.loads(output)
        except ValueError:
            output_json = json.loads(
                self.device.send_command("net show interface all json")
            )
        # Determine the current time on the system, to be used when determining the last flap
        date_format = "%Y/%m/%d %H:%M:%S"
        current_time = self._send_command("date '+{}'".format(date_format))
        current_time = datetime.strptime(current_time.strip(), date_format)
        for interface, iface_data in output_json.items():
            interfaces[interface] = {
                "description": iface_data["iface_obj"]["description"],
                "is_enabled": False if iface_data["linkstate"] == "ADMDN" else True,
                "is_up": True if iface_data["linkstate"] == "UP" else False,
                "mac_address": iface_data["iface_obj"]["mac"],
                "mtu": iface_data["iface_obj"]["mtu"],
                "speed": _convert_speed(iface_data["speed"]),
            }

        # Calculate last interface flap time. Dependent on router daemon
        # Send command to determine if router daemon is running. Not dependent on quagga or frr
        daemon_check = self._send_command("sudo vtysh -c 'show version'")
        if "Exiting: failed to connect to any daemons." in daemon_check:
            for interface in interfaces.keys():
                interfaces[interface]["last_flapped"] = -1.0
            return interfaces

        show_int_output = self._send_command("sudo vtysh -c 'show interface'")
        split_int_output = list(
            filter(None, re.split("(?!Interface Type)Interface", show_int_output))
        )
        for block in split_int_output:
            lines = block.splitlines()
            last_down = None
            last_up = None
            iface = None
            for l in lines:
                if "is up" in l or "is down" in l:
                    iface = l.split()[0].lower()
                # Grab the last two elements and make them a string
                elif "Link ups: " in l:
                    last_up = " ".join(l.split()[-2:])
                elif "Link downs: " in l:
                    last_down = " ".join(l.split()[-2:])
                    break
            # If we don't have the interface already move on
            if not interfaces.get(iface):
                continue
            # If we are unable to find either the up or the down message return -1
            if not (last_down or last_up):
                interfaces[iface]["last_flapped"] = -1.0
            # If both interfaces have never flapped return -1
            elif all(["never" in i for i in [last_up, last_down]]):
                interfaces[iface]["last_flapped"] = -1.0
            else:
                # Convert to datetime while not choking on the never
                last_down = (
                    datetime(1970, 1, 1)
                    if "never" in last_down
                    else datetime.strptime(last_down, "%Y/%m/%d %H:%M:%S.%f")
                )
                last_up = (
                    datetime(1970, 1, 1)
                    if "never" in last_up
                    else datetime.strptime(last_up, "%Y/%m/%d %H:%M:%S.%f")
                )
                # figure out which is the most recent
                most_recent = last_up if last_up > last_down else last_down
                last_flap = current_time - most_recent
                interfaces[iface]["last_flapped"] = float(last_flap.seconds)
        return interfaces

    def get_interfaces_ip(self):
        interfaces_ip = defaultdict(lambda: defaultdict(lambda: defaultdict()))
        # Get net show interface all json output.
        output = self._send_command("net show interface all json")
        # Handling bad send_command_timing return output.
        try:
            output_json = json.loads(output)
        except ValueError:
            output_json = json.loads(
                self.device.send_command("net show interface all json")
            )
        for interface in output_json:
            if not output_json[interface]["iface_obj"]["ip_address"]["allentries"]:
                continue
            for ip_address in output_json[interface]["iface_obj"]["ip_address"][
                "allentries"
            ]:
                ip_ver = ipaddress.ip_interface(ip_address).version
                ip_ver = "ipv{}".format(ip_ver)
                ip, prefix = ip_address.split("/")
                interfaces_ip[interface][ip_ver][ip] = {"prefix_length": int(prefix)}

        return interfaces_ip

    def get_config(self, retrieve="all", full=False, sanitized=False):
        # Initialise the configuration dictionary
        configuration = {"startup": "", "running": "", "candidate": ""}

        if retrieve in ("running", "all"):
            # Get net show configuration output.
            output = self._send_command("net show configuration")

            configuration["running"] = output

        if retrieve in ("candidate", "all"):
            # Get net pending output.
            output = self._send_command("net pending json")

            configuration["candidate"] = output

        return configuration

    def get_bgp_neighbors(self):
        vrf = "global"
        bgp_neighbors = {vrf: {}}
        bgp_neighbor = {}
        supported_afis = ["ipv4 unicast", "ipv6 unicast"]
        bgp_summary_output = self._send_command("net show bgp summary json")
        dev_bgp_summary = json.loads(bgp_summary_output)
        bgp_neighbors_output = self._send_command("net show bgp neighbor json")
        dev_bgp_neighbors = json.loads(bgp_neighbors_output)
        for afi in dev_bgp_summary:
            if not (afi.lower() in supported_afis) or not dev_bgp_summary[afi]:
                continue
            bgp_neighbors[vrf]["router_id"] = dev_bgp_summary[afi]["routerId"]
            bgp_neighbors[vrf].setdefault("peers", {})
            for peer in dev_bgp_summary[afi]["peers"]:
                bgp_neighbor = {}
                bgp_neighbor["local_as"] = dev_bgp_neighbors[peer]["localAs"]
                bgp_neighbor["remote_as"] = dev_bgp_neighbors[peer]["remoteAs"]
                bgp_neighbor["remote_id"] = dev_bgp_neighbors[peer]["remoteRouterId"]
                uptime = dev_bgp_neighbors[peer].get("bgpTimerUpMsec", "")
                bgp_neighbor["description"] = dev_bgp_neighbors[peer].get("nbrDesc", "")
                if dev_bgp_neighbors[peer]["bgpState"] == "Established":
                    is_up = True
                else:
                    is_up = False
                    uptime = -1
                if dev_bgp_neighbors[peer].get("adminShutDown", False):
                    is_enabled = False
                else:
                    is_enabled = True
                bgp_neighbor["is_up"] = is_up
                bgp_neighbor["is_enabled"] = is_enabled
                bgp_neighbor["uptime"] = int(uptime / 1000)
                bgp_neighbor.setdefault("address_family", {})
                for af, af_details in dev_bgp_neighbors[peer][
                    "addressFamilyInfo"
                ].items():
                    af = af.lower()
                    if not (af in supported_afis):
                        continue
                    route_info = {}
                    bgp_peer_advertised_routes = self._send_command(
                        "net show bgp {} neighbor {} "
                        "advertised-routes json".format(af, peer)
                    )
                    dev_bgp_peer_advertised_routes = json.loads(
                        bgp_peer_advertised_routes.replace("n\n", "")
                    )
                    peer_advertised_routes = dev_bgp_peer_advertised_routes[
                        "totalPrefixCounter"
                    ]
                    if not is_enabled:
                        dev_bgp_summary[af]["peers"][peer]["prefixReceivedCount"] = -1
                        peer_advertised_routes = -1
                        af_details["acceptedPrefixCounter"] = -1
                    route_info["received_prefixes"] = dev_bgp_summary[af]["peers"][
                        peer
                    ]["prefixReceivedCount"]
                    route_info["sent_prefixes"] = int(peer_advertised_routes)
                    route_info["accepted_prefixes"] = af_details[
                        "acceptedPrefixCounter"
                    ]
                    bgp_neighbor["address_family"][af.split()[0]] = route_info
                bgp_neighbors[vrf]["peers"][peer] = bgp_neighbor

        return bgp_neighbors

    def get_snmp_information(self):
        snmp_config_output = self._send_command("net show configuration snmp-server")
        contact = system_name = location = ""
        snmp_information = {}
        snmp_values = {}
        community_list = []
        snmp_values.setdefault("community", {})
        for parse_snmp_value in snmp_config_output.splitlines():
            if (
                "readonly-community" in parse_snmp_value
                or "readonly-community-v6" in parse_snmp_value
            ):
                community_value = parse_snmp_value.strip().split()[1]
                acl = parse_snmp_value.lstrip().split()[3]
                if acl == "any":
                    acl = "N/A"
                if community_value in community_list:
                    """
                    Unlike other routers that use ACL for
                    snmp access-control, Cumulus directly defines
                    authorized hosts as part of SNMP config.
                    E.g:
                    snmp-server
                       listening-address all
                       readonly-community private_multi_host access 10.10.10.1
                       system-contact NOC
                       system-location LAB
                       system-name cumulus-rtr-1
                    This creates a problem as NAPALM snmp object
                    shows access-list name as key of community string.
                    To best present the authorized-host info in the SNMP object,
                    we show comma separate string of them as key of SNMP community.
                    """
                    acl = snmp_values["community"][community_value]["acl"] + "," + acl
                    snmp_values["community"][community_value] = {
                        "acl": acl,
                        "mode": "ro",
                    }
                else:
                    community_list.append(community_value)
                    snmp_values["community"][community_value] = {
                        "acl": acl,
                        "mode": "ro",
                    }
            system_contact_parse = re.search(
                r".*system-contact.(\D.*)", parse_snmp_value.strip()
            )
            if system_contact_parse:
                contact = system_contact_parse.groups()[0]
            system_location_parse = re.search(
                r".*system-location.(\D.*)", parse_snmp_value.strip()
            )
            if system_location_parse:
                location = system_location_parse.groups()[0]
            system_name_parse = re.search(
                r".*system-name.(\D.*)", parse_snmp_value.strip()
            )
            if system_name_parse:
                system_name = system_name_parse.groups()[0]
        snmp_information = snmp_values
        snmp_information["contact"] = contact
        snmp_information["chassis_id"] = system_name
        snmp_information["location"] = location

        return snmp_information

    def cli(self, commands):
        cli_output = {}
        if type(commands) is not list:
            raise TypeError('Please enter a valid list of commands!')

        for command in commands:
            output = self.device.send_command(command)
            cli_output[command] = output
        return cli_output

    def get_vlans(self):
        """Cumulus get_vlans."""
        result = {}
        command = "net show bridge vlan json"

        try:
            output = json.loads(self._send_command(command))
        except ValueError:
            output = json.loads(self.device.send_command(command))

        for intf, data in output.items():
            for elem in data:
                if "vlanEnd" in elem:
                    start = elem["vlan"]
                    end = elem["vlanEnd"] + 1
                    vlans = range(start, end)
                else:
                    vlans = [elem["vlan"], ]
                for vlan in vlans:
                    if vlan not in result:
                        result[vlan] = {
                            "name": f"vlan{vlan}",
                            "interfaces": [intf, ]
                        }
                    else:
                        result[vlan]["interfaces"].append(intf)
        return result

    def get_mac_address_table(self):
        result = []
        command = "net show bridge macs json"

        try:
            output = json.loads(self._send_command(command))
        except ValueError:
            output = json.loads(self.device.send_command(command))

        for entry in output:
            static = False
            if "state" in entry:
                if entry["state"] == "static":
                    static = True
                else:
                    continue
            result.append({
                "mac": entry["mac"],
                "interface": entry["dev"],
                "vlan": entry["vlan"],
                "static": static,
                "active": True,
                "moves": 0,
                "last_move": 0.0
            })
        return result
示例#15
0
class NetmikoSSH(object):
    """Contains methods for managing and using SSH connections for Network Devices using Netmiko"""

    __MAX_RECV_BUF = 10 * 1024 * 1024
    __existing_connections = {}

    def __init__(self):
        self._session = None
        self._node = None
        self._device = {}

    @staticmethod
    def _node_hash(node, port):
        """Get IP address and port hash from node dictionary.

        :param node: Node in topology.
        :param port: 
        :type node: dict
        :return: IP address and port for the specified node.
        :rtype: int
        """

        return hash(frozenset([node['mgmt_ip'], port]))

    @staticmethod
    def _get_device_type(node):
        device_os = node['os']
        if str(device_os) in os_netmiko_map.keys():
            return os_netmiko_map[str(device_os)]
        return None

    def net_connect(self, node):
        """Connect to node using Netmiko's inbuilt libraries.
        :param node: The node to disconnect from.
        :type node: dict
        """
        self._node = node
        ssh_port = Topology.get_ssh_port_from_node(node)

        node_hash = NetmikoSSH._node_hash(node, ssh_port)
        if node_hash in NetmikoSSH.__existing_connections:
            self._session = NetmikoSSH.__existing_connections[node_hash]
            logger.debug('reusing ssh: {0}'.format(self._session))
        else:
            start = time()
            self._device = {
                'device_type': NetmikoSSH._get_device_type(node),
                'ip': node['mgmt_ip'],
                'username': node['username'],
                'password': node['password'],
                'port': ssh_port
            }

            self._session = ConnectHandler(**self._device)
            NetmikoSSH.__existing_connections[node_hash] = self._session

            logger.trace('connect took {} seconds'.format(time() - start))
            logger.debug('new connection: {0}'.format(self._session))

        logger.debug('Connections: {0}'.format(
            str(NetmikoSSH.__existing_connections)))

    def net_disconnect(self, node):
        """Close SSH connection to the node.

        :param node: The node to disconnect from.
        :type node: dict
        """
        ssh_port = Topology.get_ssh_port_from_node(node)

        node_hash = NetmikoSSH._node_hash(node, ssh_port)

        if node_hash in NetmikoSSH.__existing_connections:
            logger.debug('Disconnecting peer: {}, {}'.format(
                node['name'], ssh_port))
            ssh = NetmikoSSH.__existing_connections.pop(node_hash)

        self._session.disconnect()

    def _reconnect(self):
        """Close the SSH connection and open it again."""

        node = self._node
        self.net_disconnect(node)
        self.net_connect(node)

    def config_mode(self):
        """Enter into config mode """
        self.net_connect(self._node)
        self._session.config_mode()

    def check_config_mode(self):
        """ Check if session is currently in config mode"""
        self.net_connect(self._node)
        return self._session.check_config_mode()

    def exit_config_mode(self):
        """Exit config mode"""
        self.net_connect(self._node)
        self._session.exit_config_mode()

    def clear_buffer(self):
        """ Clear logging buffer """
        self.net_connect(self._node)
        self._session.clear_buffer()

    def enable(self):
        """ Enter Enable Mode"""
        self.net_connect(self._node)
        self._session.enable()

    def exit_enable_mode(self):
        """ Exit enable mode """
        self.net_connect(self._node)
        self._session.exit_enable_mode()

    def find_prompt(self):
        """Return the current router prompt"""
        self.net_connect(self._node)
        self._session.find_prompt()

    def send_command(self, cmd):
        """Send command down the SSH channel and return output back
        :param cmd
        :type cmd: str
        """
        if cmd is None:
            raise TypeError('Command parameter is None')
        if len(cmd) == 0:
            raise ValueError('Empty command parameter')

        self.net_connect(self._node)
        return self._session.send_command(cmd)

    def send_config_set(self, config_cmds):
        """Send a set of configuration commands to remote device
        :param config_cmds
        :type config_cmds: str
        """
        if config_cmds is None:
            raise TypeError('Config Cmds parameter is None')
        self.net_connect(self._node)
        print "Netmiko NODE !!!\n\n"
        print self._node
        return self._session.send_config_set(config_cmds)

    def send_config_from_file(self, cfg_file):
        """Send a set of configuration commands loaded from a file
        :param cfg_file
        :type cfg_file: file
        """
        if not os.path.isfile(cfg_file):
            raise TypeError('Config file does not exist')
        self.net_connect(self._node)
        self._session.send_config_from_file(cfg_file)