示例#1
0
def deployConfig(my_device_list_dict, my_username, my_password, my_config_template_file):
	my_hostname=""
	try:
		my_hostname=my_device_list_dict["mgmt_ip"]
		printProgress("INFO",my_hostname,"Connecting to device through netconf.")
		dev=Device(my_hostname,user=my_username,password=my_password)
		dev.open()
		dev.timeout=3*60
		cu = Config(dev)
		printProgress("INFO",my_hostname,"Going to load template the config now.")
		
		# Determine if template file is in "set" or "bracketed" format
		if isSet(my_config_template_file):
			rsp=cu.load(template_path=my_config_template_file,format='set',template_vars=my_device_list_dict)
		else:
			rsp=cu.load(template_path=my_config_template_file,template_vars=my_device_list_dict)
		
		printProgress("INFO",my_hostname,"Performing diff between active and candidate config.")
		cu.pdiff()
		printProgress("INFO",my_hostname,"Performing commit check")
		if cu.commit_check():
			printProgress("INFO",my_hostname,"commit check was successfull.")
			printProgress("INFO",my_hostname,"performing commit now.")
			commit_status=cu.commit()
			printProgress("INFO",my_hostname,"disconnecting from device.")
			dev.close()
			return commit_status
		else:
			return False
	except Exception,err:
		printProgress("ERROR",my_hostname,"Encountered exception while deploying config")
		printProgress("ERROR",my_hostname,str(err))
		return False
示例#2
0
 def test_load_config(self):
     from jnpr.junos.utils.config import Config
     cu = Config(self.dev)
     data = """interfaces {
        ge-1/0/0 {
           description "MPLS interface";
           unit 0 {
              family mpls;
           }
       }
     }
     """
     cu.load(data, format='text')
     self.assertTrue(cu.commit_check())
     if cu.commit_check():
         cu.rollback()
示例#3
0
def loadVRFConfig(VRF_number):
    if 1 < int(VRF_number) < 255:
        dev = Device(host="172.2.3.5", user="******", ssh_private_key_file="/root/.ssh/VRF")
        dev.open()

        conf = Config(dev)
        variables = {}
        variables["VRF_instance"] = VRF_number

        conf.load(template_path="templateVRF_set.conf", template_vars=variables, format="set", merge=True)
        conf.pdiff()
        if conf.commit_check():
            print "This config would commit succesfully"
        else:
            print "Config puck`d up"
        dev.close()
    else:
        print "The VRF number must be between 2 and 254"
示例#4
0
cu = Config(dev)
data = """interfaces { 
    ge-1/0/1 {
        description "MPLS interface";
        unit 0 {
            family mpls;
        }      
    } 
    ge-1/0/2 {
        description "MPLS interface";
        unit 0 {
            family mpls;
        }      
    }   
}
protocols {
    mpls { 
        interface ge-1/0/1; 
        interface ge-1/0/2;            
    }
}
"""
cu.load(data, format='text')
cu.pdiff()
if cu.commit_check():
   cu.commit()
else:
   cu.rollback()

dev.close()
class TestConfig(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()
        self.conf = Config(self.dev)

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

    def test_config_constructor(self):
        self.assertTrue(isinstance(self.conf._dev, Device))

    def test_config_confirm_true(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(confirmed=True)

    def test_config_commit_confirm(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=10)
        self.conf.rpc.commit_configuration\
            .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True})

    def test_config_commit_comment(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(comment='Test')
        self.conf.rpc.commit_configuration.assert_called_with(log='Test')

    def test_config_commit_sync(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(sync=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(synchronize=True)

    def test_config_commit_force_sync(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(force_sync=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(**{'synchronize': True, 'force-synchronize': True})

    def test_config_commit_timeout(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(timeout=60)
        self.conf.rpc.commit_configuration\
            .assert_called_with(dev_timeout=60)

    def test_config_commit_full(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(full=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(full=True)

    def test_config_commit_detail(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.rpc.commit_configuration.return_value = '<mockdetail/>'
        self.assertEqual('<mockdetail/>', self.conf.commit(detail=True))
        self.conf.rpc.commit_configuration\
            .assert_called_with({'detail': 'detail'})

    def test_config_commit_combination(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.rpc.commit_configuration.return_value = '<moredetail/>'
        self.assertEqual(
            '<moredetail/>',
            self.conf.commit(
                detail=True,
                force_sync=True,
                full=True))
        self.conf.rpc.commit_configuration\
            .assert_called_with({'detail': 'detail'},
                                **{'synchronize': True, 'full': True, 'force-synchronize': True})

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_commit_xml_exception(self, mock_jxml):
        class MyException(Exception):
            xml = etree.fromstring('<test/>')
        self.conf.rpc.commit_configuration = \
            MagicMock(side_effect=MyException)
        self.assertRaises(CommitError, self.conf.commit)

    def test_config_commit_exception(self):
        class MyException(Exception):
            pass
        self.conf.rpc.commit_configuration = \
            MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.conf.commit)

    def test_config_commit_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit)

    def test_commit_check(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit_check())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_commit_check_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        # with self.assertRaises(AttributeError):
        self.conf.commit_check()

    def test_config_commit_check_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit_check())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit_check)

    def test_config_diff(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.conf.diff()
        self.conf.rpc.get_configuration.\
            assert_called_with(
                {'compare': 'rollback', 'rollback': '0', 'format': 'text'})

    def test_config_diff_exception_severity_warning(self):
        rpc_xml = '''
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>mgd: statement must contain additional statements</error-message>
        </rpc-error>
        '''
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.get_configuration = MagicMock(
            side_effect=RpcError(rsp=rsp))
        self.assertEqual(self.conf.diff(),
                         "Unable to parse diff from response!")

    def test_config_diff_exception_severity_warning_still_raise(self):
        rpc_xml = '''
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>statement not found</error-message>
        </rpc-error>
        '''
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.get_configuration = MagicMock(
            side_effect=RpcError(rsp=rsp))
        self.assertRaises(RpcError, self.conf.diff)

    def test_config_pdiff(self):
        self.conf.diff = MagicMock(return_value='Stuff')
        self.conf.pdiff()
        self.conf.diff.assert_called_once_with(0)

    def test_config_load(self):
        self.assertRaises(RuntimeError, self.conf.load)

    def test_config_load_vargs_len(self):
        self.assertRaises(RuntimeError, self.conf.load,
                          'test.xml')

    def test_config_load_len_with_format_set(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertEqual(self.conf.load('test.xml', format='set'),
                         'rpc_contents')

    def test_config_load_len_with_format_xml(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        xmldata = """<snmp>
          <community>
            <name>iBGP</name>
          </community>
        </snmp>"""

        self.assertEqual(self.conf.load(xmldata, format='xml'),
                         'rpc_contents')

    def test_config_load_len_with_format_text(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        textdata = """policy-options {
    prefix-list TEST1-NETS {
        100.0.0.0/24;
    }
    policy-statement TEST1-NETS {
        term TEST1 {
            from {
                prefix-list TEST1-NETS;
            }
            then accept;
        }
        term REJECT {
            then reject;
        }
    }
}"""

        self.assertEqual(self.conf.load(textdata), 'rpc_contents')

    def test_config_load_with_format_json(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value=etree.fromstring("""<load-configuration-results>
                            <ok/>
                        </load-configuration-results>"""))
        op = self.conf.load('test.json', format='json')
        self.assertEqual(op.tag, 'load-configuration-results')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'json')

    @patch(builtin_string + '.open')
    def test_config_load_with_format_json_from_file_ext(self, mock_open):
        self.conf.rpc.load_config = \
            MagicMock(return_value=etree.fromstring("""<load-configuration-results>
                            <ok/>
                        </load-configuration-results>"""))
        op = self.conf.load(path='test.json')
        self.assertEqual(op.tag, 'load-configuration-results')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'json')

    @patch(builtin_string + '.open')
    def test_config_load_update(self, mock_open):
        self.conf.rpc.load_config = \
            MagicMock(return_value=etree.fromstring("""<load-configuration-results>
                            <ok/>
                        </load-configuration-results>"""))
        op = self.conf.load(path='test.conf', update=True)
        self.assertEqual(op.tag, 'load-configuration-results')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    def test_config_load_update_merge_overwrite(self):
        self.assertRaises(ValueError, self.conf.load, path='test.jnpr',
                          update=True, merge=True, overwrite=True)

    @patch(builtin_string + '.open')
    def test_config_load_lformat_byext_ValueError(self, mock_open):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load, path='test.jnpr')

    def test_config_load_lset_format_ValueError(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load,
                          'test.xml', format='set', overwrite=True)

    @patch(builtin_string + '.open')
    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_path_xml(self, mock_etree, mock_open):
        self.conf.dev.Template = MagicMock()
        mock_etree.return_value = 'rpc_contents'
        self.conf.rpc.load_config = \
            MagicMock(return_value=mock_etree.return_value)
        self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents')

    @patch(builtin_string + '.open')
    def test_config_load_path_text(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.conf')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    @patch(builtin_string + '.open')
    def test_config_load_path_set(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.set')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    @patch(builtin_string + '.open')
    def test_config_load_try_load_rpcerror(self, mock_open):
        ex = ConfigLoadError(
            rsp=etree.fromstring((
                """<load-configuration-results>
                <rpc-error>
                <error-severity>error</error-severity>
                <error-message>syntax error</error-message>
                </rpc-error>
                </load-configuration-results>""")))
        self.conf.rpc.load_config = MagicMock(side_effect=ex)
        self.assertRaises(ConfigLoadError, self.conf.load, path='config.conf')

    @patch(builtin_string + '.open')
    def test_config_load_try_load_rpctimeouterror(self, mock_open):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.load_config = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.load, path='config.conf')

    @patch(builtin_string + '.open')
    def test_config_try_load_exception(self, mock_open):
        class OtherException(Exception):
            pass
        self.conf.rpc.load_config = MagicMock(side_effect=OtherException())
        self.assertRaises(OtherException, self.conf.load, path='config.conf')

    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_template_path(self, mock_etree):
        self.conf.rpc.load_config = MagicMock()
        self.conf.dev.Template = MagicMock()
        self.conf.load(template_path='test.xml')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_load_template(self):
        class Temp:
            filename = 'abc.xml'
            render = MagicMock(return_value='<test/>')
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(template=Temp)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_diff_exception(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.diff, 51)
        self.assertRaises(ValueError, self.conf.diff, -1)

    def test_config_lock(self):
        self.conf.rpc.lock_configuration = MagicMock()
        self.assertTrue(self.conf.lock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_lock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.lock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(LockError, self.conf.lock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_lock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(LockError, self.conf.lock)

    def test_config_unlock(self):
        self.conf.rpc.unlock_configuration = MagicMock()
        self.assertTrue(self.conf.unlock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_unlock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(UnlockError, self.conf.unlock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_unlock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(UnlockError, self.conf.unlock)

    def test_config_rollback(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertTrue(self.conf.rollback())

    def test_config_rollback_exception(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.rollback, 51)
        self.assertRaises(ValueError, self.conf.rollback, -1)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_save(self, mock_exec):
        self.dev.request_save_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue('save'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_get_exception(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception)
        self.assertTrue(self.conf.rescue('get') is None)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_get(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock()
        self.dev.rpc.get_rescue_information.return_value = 1
        self.assertEqual(self.conf.rescue('get', format='xml'), 1)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_delete(self, mock_exec):
        self.dev.rpc.request_delete_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue('delete'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_reload(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock()
        self.dev.rpc.load_configuration.return_value = True
        self.assertTrue(self.conf.rescue('reload'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_reload_exception(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock(side_effect=Exception)
        self.assertFalse(self.conf.rescue('reload'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_unsupported_action(self, mock_exec):
        self.assertRaises(ValueError, self.conf.rescue, 'abc')

    def test_config_load_lset_from_rexp_xml(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """<snmp><name>iBGP</name></snmp>"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_load_lset_from_rexp_json(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """{
            "configuration" : {
                "system" : {
                    "services" : {
                        "telnet" : [null]
                    }
                }
            }
        }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'json')

    def test_config_load_lset_from_rexp_set(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """set system domain-name englab.nitin.net"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_lset_from_rexp_set_delete(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """delete snmp"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_lset_from_rexp_conf(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    def test_config_load_lset_from_rexp_conf_replace_tag(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """replace:
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'replace')

    def test_config_load_lset_from_rexp_error(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """test>"""
        self.assertRaises(RuntimeError, self.conf.load, conf)

    def test_load_merge_true(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf, merge=True)
        self.assertFalse('action' in self.conf.rpc.load_config.call_args[1])

    def test_commit_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.dev.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.commit)

    def test_commit_check_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.dev.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.commit_check)

    def test_commit_configuration_multi_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        try:
            self.dev.rpc.commit_configuration()
        except Exception as ex:
            self.assertTrue(isinstance(ex, RpcError))
            if ncclient.__version__ > (0, 4, 5):
                self.assertEqual(ex.message,
                                 "error: interface-range 'axp' is not defined\n"
                                 "error: interface-ranges expansion failed")
                self.assertEqual(ex.errs, [{'source': None, 'message':
                                            "interface-range 'axp' is not defined", 'bad_element': None, 'severity':
                                            'error', 'edit_path': None}, {'source': None, 'message':
                                                                          'interface-ranges expansion failed', 'bad_element': None,
                                                                          'severity': 'error', 'edit_path': None}])
            else:
                self.assertEqual(ex.message,
                                 "interface-range 'axp' is not defined")

    @patch('jnpr.junos.utils.config.Config.lock')
    @patch('jnpr.junos.utils.config.Config.unlock')
    def test_config_mode_exclusive(self, mock_unlock, mock_lock):
        with Config(self.dev, mode='exclusive') as conf:
            conf.rpc.load_config = MagicMock()
            conf.load('conf', format='set')
        self.assertTrue(mock_lock.called and mock_unlock.called)

    @patch('jnpr.junos.Device.execute')
    def test_config_mode_batch(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode='batch') as conf:
            conf.load('conf', format='set')
        self.dev.rpc.open_configuration.assert_called_with(batch=True)

    @patch('jnpr.junos.Device.execute')
    def test_config_mode_private(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode='private') as conf:
            conf.load('conf', format='set')
        self.dev.rpc.open_configuration.assert_called_with(private=True)

    @patch('jnpr.junos.Device.execute')
    def test_config_mode_dynamic(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode='dynamic') as conf:
            conf.load('conf', format='set')
        self.dev.rpc.open_configuration.assert_called_with(dynamic=True)

    @patch('jnpr.junos.Device.execute')
    def test_config_mode_close_configuration_ex(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        ex = RpcError(rsp='ok')
        ex.message = 'Configuration database is not open'
        self.dev.rpc.close_configuration = MagicMock(side_effect=ex)
        try:
            with Config(self.dev, mode='batch') as conf:
                conf.load('conf', format='set')
        except Exception as ex:
            self.assertTrue(isinstance(ex, RpcError))
        self.assertTrue(self.dev.rpc.close_configuration.called)

    @patch('jnpr.junos.Device.execute')
    def test_config_mode_undefined(self, mock_exec):
        try:
            with Config(self.dev, mode='unknown') as conf:
                conf.load('conf', format='set')
        except Exception as ex:
            self.assertTrue(isinstance(ex, ValueError))

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.utils.config.warnings')
    def test_config_mode_batch_open_configuration_ex(self,
                                                     mock_warnings, mock_exec):
        rpc_xml = '''
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>syntax error</error-message>
        </rpc-error>
        '''
        rsp = etree.XML(rpc_xml)
        obj = RpcError(rsp=rsp)
        self.dev.rpc.open_configuration = MagicMock(side_effect=obj)
        with Config(self.dev, mode='batch') as conf:
            conf.load('conf', format='set')
        self.dev.rpc.open_configuration.assert_called_with(batch=True)

    @patch('jnpr.junos.Device.execute')
    @patch('jnpr.junos.utils.config.warnings')
    def test_config_mode_private_open_configuration_ex(self,
                                                       mock_warnings,
                                                       mock_exec):
        rpc_xml = '''
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>syntax error</error-message>
        </rpc-error>
        '''
        rsp = etree.XML(rpc_xml)
        obj = RpcError(rsp=rsp)
        self.dev.rpc.open_configuration = MagicMock(side_effect=obj)
        with Config(self.dev, mode='private') as conf:
            conf.load('conf', format='set')
        self.dev.rpc.open_configuration.assert_called_with(private=True)

    def test__enter__private_exception_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.open_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, Config.__enter__,
                          Config(self.dev, mode='private'))

    def test__enter__private_exception_RpcError(self):
        rpc_xml = """<rpc-error>
            <error-severity>error</error-severity>
            <error-message>syntax error</error-message>
            </rpc-error>"""
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.open_configuration = \
            MagicMock(side_effect=RpcError(rsp=rsp))
        self.assertRaises(RpcError, Config.__enter__,
                          Config(self.dev, mode='private'))

    def test__enter__dyanamic_exception_RpcError(self):
        rpc_xml = """<rpc-error>
            <error-severity>error</error-severity>
            <error-message>syntax error</error-message>
            </rpc-error>"""
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.open_configuration = \
            MagicMock(side_effect=RpcError(rsp=rsp))
        self.assertRaises(RpcError, Config.__enter__,
                          Config(self.dev, mode='dynamic'))

    def test__enter__batch_exception_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.open_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, Config.__enter__,
                          Config(self.dev, mode='batch'))

    def test__enter__batch_exception_RpcError(self):
        rpc_xml = """<rpc-error>
            <error-severity>error</error-severity>
            <error-message>syntax error</error-message>
            </rpc-error>"""
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.open_configuration = \
            MagicMock(side_effect=RpcError(rsp=rsp))
        self.assertRaises(RpcError, Config.__enter__,
                          Config(self.dev, mode='batch'))

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

        # specific to multi rpc error
        if fname == 'commit-configuration.xml':
            raw = etree.XML(foo)
            obj = RPCReply(raw)
            obj.parse()
            if ncclient.__version__ > (0, 4, 5):
                raise RPCError(etree.XML(foo), errs=obj._errors)
            else:
                raise RPCError(etree.XML(foo))

    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:
            return self._read_file(args[0].tag + '.xml')
示例#6
0
class TestConfig(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')
        self.conf = Config(self.dev)

    def test_config_constructor(self):
        self.assertTrue(isinstance(self.conf._dev, Device))

    def test_config_confirm(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit(confirm=True))

    def test_config_commit_confirm_timeout(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=10)
        self.conf.rpc.commit_configuration\
            .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True})

    def test_config_commit_comment(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(comment='Test')
        self.conf.rpc.commit_configuration.assert_called_with(log='Test')

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_commit_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.commit_configuration = \
            MagicMock(side_effect=MyException)
        self.assertRaises(AttributeError, self.conf.commit)

    def test_config_commit_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit)

    def test_commit_check(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit_check())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_commit_check_exception(self, mock_jxml):
        class MyException(Exception):
                xml = 'test'
        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        # with self.assertRaises(AttributeError):
        self.conf.commit_check()

    def test_config_commit_check_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit_check())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit_check)

    def test_config_diff(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.conf.diff()
        self.conf.rpc.get_configuration.\
            assert_called_with({'compare': 'rollback', 'rollback': '0', 'format': 'text'})

    def test_config_pdiff(self):
        self.conf.diff = MagicMock(return_value='Stuff')
        self.conf.pdiff()
        print self.conf.diff.call_args
        self.conf.diff.assert_called_once_with(0)

    def test_config_load(self):
        self.assertRaises(RuntimeError, self.conf.load)

    def test_config_load_vargs_len(self):
        self.assertRaises(RuntimeError, self.conf.load,
                          'test.xml')

    def test_config_load_len_with_format(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertEqual(self.conf.load('test.xml', format='set'),
                         'rpc_contents')

    @patch('__builtin__.open')
    def test_config_load_lformat_byext_ValueError(self, mock_open):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load, path='test.jnpr')

    def test_config_load_lset_format_ValueError(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load,
                          'test.xml', format='set', overwrite=True)

    @patch('__builtin__.open')
    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_path_xml(self, mock_etree, mock_open):
        self.conf.dev.Template = MagicMock()
        mock_etree.return_value = 'rpc_contents'
        self.conf.rpc.load_config = \
            MagicMock(return_value=mock_etree.return_value)
        self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents')

    @patch('__builtin__.open')
    def test_config_load_path_text(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.conf')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    @patch('__builtin__.open')
    def test_config_load_path_set(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.set')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_template_path(self):
        self.conf.rpc.load_config = MagicMock()
        self.conf.dev.Template = MagicMock()
        self.conf.load(template_path='test.xml')
        self.conf.dev.Template.assert_called_with('test.xml')

    def test_config_load_template(self):
        class Temp:
            filename = 'abc.xml'
            render = MagicMock()
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(template=Temp)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_diff_exception(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.diff, 51)
        self.assertRaises(ValueError, self.conf.diff, -1)

    def test_config_lock(self):
        self.conf.rpc.lock_configuration = MagicMock()
        self.assertTrue(self.conf.lock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_lock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.lock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(LockError, self.conf.lock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_lock_exception(self, mock_jxml):
        class MyException(Exception):
                xml = 'test'
        self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(LockError, self.conf.lock)

    def test_config_unlock(self):
        self.conf.rpc.unlock_configuration = MagicMock()
        self.assertTrue(self.conf.unlock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_unlock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(UnlockError, self.conf.unlock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_unlock_exception(self, mock_jxml):
        class MyException(Exception):
                xml = 'test'
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(UnlockError, self.conf.unlock)

    def test_config_rollback(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertTrue(self.conf.rollback())

    def test_config_rollback_exception(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.rollback, 51)
        self.assertRaises(ValueError, self.conf.rollback, -1)
示例#7
0
    def apply_template(self, template):
        print self.dev
        conf_string = template.strip()

        print conf_string

        if re.search(r"^&lt;", conf_string):
            print "Found a encoded string"
            conf_string = self.unescape(conf_string)

        print conf_string
        # try to determine the format of our config_string
        config_format = "set"
        if re.search(r"^\s*<.*>$", conf_string, re.MULTILINE):
            print "found xml style config"
            config_format = "xml"
        elif re.search(r"^\s*(set|delete|replace|rename)\s", conf_string):
            print "found set style config"
            config_format = "set"
        elif re.search(r"^[a-z:]*\s*\w+\s+{", conf_string, re.I) and re.search(r".*}\s*$", conf_string):
            print "found a text style config"
            config_format = "text"

        print "using format: " + config_format
        cu = Config(self.dev)
        try:
            cu.lock()
        except LockError as le:
            print "Could not lock database!"
            print str(le)
            self.dev.close()
            return "Failed to lock configuration database! %s" % str(le)

        try:
            print "loading config"
            cu.load(conf_string, format=config_format)
        except Exception as e:
            print "Could not load configuration"
            print str(e)
            try:
                cu.unlock()
            except UnlockError as ue:
                print str(ue)

            self.dev.close()
            return "Failed, could not load the configuration template. %s" % str(e)

        diff = cu.diff()
        print diff
        if diff is not None:
            try:
                cu.commit_check()
                print "Committing config!"
                cu.commit(comment="Commit via a_frame")

            except CommitError as ce:
                print "Could not load config! %s" % str(ce)
                cu.rollback()
                try:
                    print "Unlocking database!"
                    cu.unlock()
                except UnlockError as ue:
                    print "Could not unlock database"
                    print str(ue)
                print repr(ce)
                self.dev.close()
                return "Failed, commit check failed. %s" % str(ce)

        else:
            # nothing to commit
            print "Nothing to commit - no diff found"
            cu.unlock()
            self.dev.close()
            return "Nothing to commit!"

        try:
            print "Unlocking database!"
            cu.unlock()
        except UnlockError as ue:
            print "Could not unlock database"
            print str(ue)
            self.dev.close()
            return "Committed, but could not unlock db"

        print "Closing device handle"
        self.dev.close()
        return "Completed with diff: %s" % diff
示例#8
0
class Netconf(object):

    def __init__(self):
        self.device = None
        self.config = None
        self._locked = False
        self._connected = False
        self.default_output = 'xml'

    def raise_exc(self, msg):
        if self.device:
            if self._locked:
                self.config.unlock()
            self.disconnect()
        raise NetworkError(msg)

    def connect(self, params, **kwargs):
        host = params['host']
        port = params.get('port') or 830

        user = params['username']
        passwd = params['password']

        try:
            self.device = Device(host, user=user, passwd=passwd, port=port,
                                 gather_facts=False)
            self.device.open()
        except ConnectError:
            exc = get_exception()
            self.raise_exc('unable to connect to %s: %s' % (host, str(exc)))

        self.config = Config(self.device)
        self._connected = True

    def disconnect(self):
        if self.device:
            self.device.close()
        self._connected = False

    ### Command methods ###

    def run_commands(self, commands):
        responses = list()

        for cmd in commands:
            meth = getattr(self, cmd.args.get('command_type'))
            responses.append(meth(str(cmd), output=cmd.output))

        for index, cmd in enumerate(commands):
            if cmd.output == 'xml':
                responses[index] = etree.tostring(responses[index])
            elif cmd.args.get('command_type') == 'rpc':
                responses[index] = str(responses[index].text).strip()

        return responses

    def cli(self, commands, output='xml'):
        '''Send commands to the device.'''
        try:
            return self.device.cli(commands, format=output, warning=False)
        except (ValueError, RpcError):
            exc = get_exception()
            self.raise_exc('Unable to get cli output: %s' % str(exc))

    def rpc(self, command, output='xml'):
        name, kwargs = rpc_args(command)
        meth = getattr(self.device.rpc, name)
        reply = meth({'format': output}, **kwargs)
        return reply

    ### Config methods ###

    def get_config(self, config_format="text"):
        if config_format not in SUPPORTED_CONFIG_FORMATS:
            self.raise_exc(msg='invalid config format.  Valid options are '
                               '%s' % ', '.join(SUPPORTED_CONFIG_FORMATS))

        ele = self.rpc('get_configuration', output=config_format)

        if config_format in ['text', 'set']:
            return str(ele.text).strip()
        else:
            return ele

    def load_config(self, candidate, update='merge', comment=None,
                    confirm=None, format='text', commit=True):

        merge = update == 'merge'
        overwrite = update == 'overwrite'

        self.lock_config()

        try:
            candidate = '\n'.join(candidate)
            self.config.load(candidate, format=format, merge=merge,
                             overwrite=overwrite)
        except ConfigLoadError:
            exc = get_exception()
            self.raise_exc('Unable to load config: %s' % str(exc))

        diff = self.config.diff()

        self.check_config()

        if all((commit, diff)):
            self.commit_config(comment=comment, confirm=confirm)

        self.unlock_config()

        return diff

    def save_config(self):
        raise NotImplementedError

    ### end of Config ###

    def get_facts(self, refresh=True):
        if refresh:
            self.device.facts_refresh()
        return self.device.facts

    def unlock_config(self):
        try:
            self.config.unlock()
            self._locked = False
        except UnlockError:
            exc = get_exception()
            raise NetworkError('unable to unlock config: %s' % str(exc))

    def lock_config(self):
        try:
            self.config.lock()
            self._locked = True
        except LockError:
            exc = get_exception()
            raise NetworkError('unable to lock config: %s' % str(exc))

    def check_config(self):
        if not self.config.commit_check():
            self.raise_exc(msg='Commit check failed')

    def commit_config(self, comment=None, confirm=None):
        try:
            kwargs = dict(comment=comment)
            if confirm and confirm > 0:
                kwargs['confirm'] = confirm
            return self.config.commit(**kwargs)
        except CommitError:
            exc = get_exception()
            raise NetworkError('unable to commit config: %s' % str(exc))

    def rollback_config(self, identifier, commit=True, comment=None):

        self.lock_config()

        try:
            self.config.rollback(identifier)
        except ValueError:
            exc = get_exception()
            self._error('Unable to rollback config: $s' % str(exc))

        diff = self.config.diff()
        if commit:
            self.commit_config(comment=comment)

        self.unlock_config()
        return diff
示例#9
0
class TestConfig(unittest.TestCase):
    def setUp(self):
        self.dev = Device(host='1.1.1.1')
        self.conf = Config(self.dev)

    def test_config_constructor(self):
        self.assertTrue(isinstance(self.conf._dev, Device))

    def test_config_confirm(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit(confirm=True))

    def test_config_commit_confirm_timeout(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=10)
        self.conf.rpc.commit_configuration\
            .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True})

    def test_config_commit_comment(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(comment='Test')
        self.conf.rpc.commit_configuration.assert_called_with(log='Test')

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_commit_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.commit_configuration = \
            MagicMock(side_effect=MyException)
        self.assertRaises(AttributeError, self.conf.commit)

    def test_config_commit_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit)

    def test_commit_check(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit_check())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_commit_check_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'

        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        # with self.assertRaises(AttributeError):
        self.conf.commit_check()

    def test_config_commit_check_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit_check())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit_check)

    def test_config_diff(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.conf.diff()
        self.conf.rpc.get_configuration.\
            assert_called_with(
                {'compare': 'rollback', 'rollback': '0', 'format': 'text'})

    def test_config_pdiff(self):
        self.conf.diff = MagicMock(return_value='Stuff')
        self.conf.pdiff()
        self.conf.diff.assert_called_once_with(0)

    def test_config_load(self):
        self.assertRaises(RuntimeError, self.conf.load)

    def test_config_load_vargs_len(self):
        self.assertRaises(RuntimeError, self.conf.load, 'test.xml')

    def test_config_load_len_with_format_set(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertEqual(self.conf.load('test.xml', format='set'),
                         'rpc_contents')

    def test_config_load_len_with_format_xml(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        xmldata = """<snmp>
          <community>
            <name>iBGP</name>
          </community>
        </snmp>"""

        self.assertEqual(self.conf.load(xmldata, format='xml'), 'rpc_contents')

    @patch('__builtin__.open')
    def test_config_load_lformat_byext_ValueError(self, mock_open):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load, path='test.jnpr')

    def test_config_load_lset_format_ValueError(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError,
                          self.conf.load,
                          'test.xml',
                          format='set',
                          overwrite=True)

    @patch('__builtin__.open')
    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_path_xml(self, mock_etree, mock_open):
        self.conf.dev.Template = MagicMock()
        mock_etree.return_value = 'rpc_contents'
        self.conf.rpc.load_config = \
            MagicMock(return_value=mock_etree.return_value)
        self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents')

    @patch('__builtin__.open')
    def test_config_load_path_text(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.conf')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    @patch('__builtin__.open')
    def test_config_load_path_set(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.set')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    @patch('__builtin__.open')
    def test_config_load_try_load_exception(self, mock_open):
        ex = RpcError(rsp=etree.fromstring(("""<load-configuration-results>
                <rpc-error>
                <error-severity>error</error-severity>
                <error-message>syntax error</error-message>
                </rpc-error>
                </load-configuration-results>""")))
        self.conf.rpc.load_config = MagicMock(side_effect=ex)
        self.assertRaises(RpcError, self.conf.load, path='config.conf')

    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_template_path(self, mock_etree):
        self.conf.rpc.load_config = MagicMock()
        self.conf.dev.Template = MagicMock()
        self.conf.load(template_path='test.xml')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_load_template(self):
        class Temp:
            filename = 'abc.xml'
            render = MagicMock(return_value='<test/>')

        self.conf.rpc.load_config = MagicMock()
        self.conf.load(template=Temp)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_diff_exception(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.diff, 51)
        self.assertRaises(ValueError, self.conf.diff, -1)

    def test_config_lock(self):
        self.conf.rpc.lock_configuration = MagicMock()
        self.assertTrue(self.conf.lock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_lock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.lock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(LockError, self.conf.lock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_lock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'

        self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(LockError, self.conf.lock)

    def test_config_unlock(self):
        self.conf.rpc.unlock_configuration = MagicMock()
        self.assertTrue(self.conf.unlock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_unlock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(UnlockError, self.conf.unlock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_unlock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'

        self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(UnlockError, self.conf.unlock)

    def test_config_rollback(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertTrue(self.conf.rollback())

    def test_config_rollback_exception(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.rollback, 51)
        self.assertRaises(ValueError, self.conf.rollback, -1)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_save(self, mock_exec):
        self.dev.request_save_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue('save'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_get_exception(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception)
        self.assertTrue(self.conf.rescue('get') is None)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_get(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock()
        self.dev.rpc.get_rescue_information.return_value = 1
        self.assertEqual(self.conf.rescue('get', format='xml'), 1)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_delete(self, mock_exec):
        self.dev.rpc.request_delete_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue('delete'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_reload(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock()
        self.dev.rpc.load_configuration.return_value = True
        self.assertTrue(self.conf.rescue('reload'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_reload_exception(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock(side_effect=Exception)
        self.assertFalse(self.conf.rescue('reload'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_unsupported_action(self, mock_exec):
        self.assertRaises(ValueError, self.conf.rescue, 'abc')

    def test_config_load_lset_from_rexp_xml(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """<snmp><name>iBGP</name></snmp>"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_load_lset_from_rexp_set(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """set system domain-name englab.nitin.net"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_lset_from_rexp_set_delete(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """delete snmp"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_lset_from_rexp_conf(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    def test_config_load_lset_from_rexp_conf_replace_tag(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """replace:
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'replace')

    def test_config_load_lset_from_rexp_error(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """nitin>"""
        self.assertRaises(RuntimeError, self.conf.load, conf)

    def test_load_merge_true(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf, merge=True)
        self.assertFalse('action' in self.conf.rpc.load_config.call_args[1])

    def test_commit_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.dev.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.commit)
示例#10
0
class TestConfig(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()
        self.conf = Config(self.dev)

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

    def test_config_constructor(self):
        self.assertTrue(isinstance(self.conf._dev, Device))

    def test_config_confirm_true(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=True)
        self.conf.rpc.commit_configuration.assert_called_with(confirmed=True)

    def test_config_commit_confirm(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=10)
        self.conf.rpc.commit_configuration.assert_called_with(
            **{
                "confirm-timeout": "10",
                "confirmed": True
            })

    def test_config_commit_comment(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(comment="Test")
        self.conf.rpc.commit_configuration.assert_called_with(log="Test")

    def test_config_commit_sync(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(sync=True)
        self.conf.rpc.commit_configuration.assert_called_with(synchronize=True)

    def test_config_commit_force_sync(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(force_sync=True)
        self.conf.rpc.commit_configuration.assert_called_with(
            **{
                "synchronize": True,
                "force-synchronize": True
            })

    def test_config_commit_timeout(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(timeout=60)
        self.conf.rpc.commit_configuration.assert_called_with(dev_timeout=60)

    def test_config_commit_full(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(full=True)
        self.conf.rpc.commit_configuration.assert_called_with(full=True)

    def test_config_commit_detail(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.rpc.commit_configuration.return_value = "<mockdetail/>"
        self.assertEqual("<mockdetail/>", self.conf.commit(detail=True))
        self.conf.rpc.commit_configuration.assert_called_with(
            {"detail": "detail"})

    def test_config_commit_combination(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.rpc.commit_configuration.return_value = "<moredetail/>"
        self.assertEqual(
            "<moredetail/>",
            self.conf.commit(detail=True, force_sync=True, full=True))
        self.conf.rpc.commit_configuration.assert_called_with(
            {"detail": "detail"}, **{
                "synchronize": True,
                "full": True,
                "force-synchronize": True
            })

    @patch("jnpr.junos.utils.config.JXML.remove_namespaces")
    def test_config_commit_xml_exception(self, mock_jxml):
        class MyException(Exception):
            xml = etree.fromstring("<test/>")

        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(CommitError, self.conf.commit)

    def test_config_commit_exception(self):
        class MyException(Exception):
            pass

        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(MyException, self.conf.commit)

    def test_config_commit_exception_RpcError(self):
        ex = RpcError(rsp="ok")
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit())
        import xml.etree.ElementTree as ET

        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find("company")
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit)

    def test_commit_check(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit_check())

    # @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_commit_check_exception(self):
        class MyException(Exception):
            xml = etree.fromstring("""
            <rpc-reply>
<rpc-error>
<error-type>protocol</error-type>
<error-tag>operation-failed</error-tag>
<error-severity>error</error-severity>
<error-message>permission denied</error-message>
<error-info>
<bad-element>system</bad-element>
</error-info>
</rpc-error>
</rpc-reply>
            """)

        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        # with self.assertRaises(AttributeError):
        self.assertDictEqual(
            self.conf.commit_check(),
            {
                "source": None,
                "message": "permission denied",
                "bad_element": "system",
                "severity": "error",
                "edit_path": None,
            },
        )

    def test_config_commit_check_exception_RpcError(self):
        ex = RpcError(rsp="ok")
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit_check())
        import xml.etree.ElementTree as ET

        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find("company")
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit_check)

    def test_config_diff(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.conf.diff()
        self.conf.rpc.get_configuration.assert_called_with(
            {
                "compare": "rollback",
                "rollback": "0",
                "format": "text"
            },
            ignore_warning=False,
        )

    def test_config_diff_use_fast_diff(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.conf.diff(use_fast_diff=True)
        self.conf.rpc.get_configuration.assert_called_with(
            {
                "compare": "rollback",
                "rollback": "0",
                "format": "text",
                "use-fast-diff": "yes",
            },
            ignore_warning=False,
        )

    def test_config_diff_use_fast_diff_rb_id_gt_0(self):
        self.conf.rpc.get_configuration = MagicMock()
        with self.assertRaises(ValueError):
            self.conf.diff(use_fast_diff=True, rb_id=1)

    def test_config_diff_exception_severity_warning(self):
        rpc_xml = """
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>mgd: statement must contain additional statements</error-message>
        </rpc-error>
        """
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.get_configuration = MagicMock(side_effect=RpcError(
            rsp=rsp))
        self.assertEqual(self.conf.diff(),
                         "Unable to parse diff from response!")

    def test_config_diff_exception_severity_warning_still_raise(self):
        rpc_xml = """
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>statement not found</error-message>
        </rpc-error>
        """
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.get_configuration = MagicMock(side_effect=RpcError(
            rsp=rsp))
        self.assertRaises(RpcError, self.conf.diff)

    def test_config_pdiff(self):
        self.conf.diff = MagicMock(return_value="Stuff")
        self.conf.pdiff()
        self.conf.diff.assert_called_once_with(0, False, False)

    def test_config_diff_rpc_timeout(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.get_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.diff)

    def test_config_load(self):
        self.assertRaises(RuntimeError, self.conf.load)

    def test_config_load_vargs_len(self):
        self.assertRaises(RuntimeError, self.conf.load, "test.xml")

    def test_config_load_len_with_format_set(self):
        self.conf.rpc.load_config = MagicMock(return_value="rpc_contents")
        self.assertEqual(self.conf.load("test.xml", format="set"),
                         "rpc_contents")

    def test_config_load_len_with_format_xml(self):
        self.conf.rpc.load_config = MagicMock(return_value="rpc_contents")
        xmldata = """<snmp>
          <community>
            <name>iBGP</name>
          </community>
        </snmp>"""

        self.assertEqual(self.conf.load(xmldata, format="xml"), "rpc_contents")

    def test_config_load_len_with_format_text(self):
        self.conf.rpc.load_config = MagicMock(return_value="rpc_contents")
        textdata = """policy-options {
    prefix-list TEST1-NETS {
        100.0.0.0/24;
    }
    policy-statement TEST1-NETS {
        term TEST1 {
            from {
                prefix-list TEST1-NETS;
            }
            then accept;
        }
        term REJECT {
            then reject;
        }
    }
}"""

        self.assertEqual(self.conf.load(textdata), "rpc_contents")

    def test_config_load_with_format_json(self):
        self.conf.rpc.load_config = MagicMock(
            return_value=etree.fromstring("""<load-configuration-results>
                            <ok/>
                        </load-configuration-results>"""))
        op = self.conf.load("test.json", format="json")
        self.assertEqual(op.tag, "load-configuration-results")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "json")

    @patch(builtin_string + ".open")
    def test_config_load_with_format_json_from_file_ext(self, mock_open):
        self.conf.rpc.load_config = MagicMock(
            return_value=etree.fromstring("""<load-configuration-results>
                            <ok/>
                        </load-configuration-results>"""))
        op = self.conf.load(path="test.json")
        self.assertEqual(op.tag, "load-configuration-results")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "json")

    @patch(builtin_string + ".open")
    def test_config_load_update(self, mock_open):
        self.conf.rpc.load_config = MagicMock(
            return_value=etree.fromstring("""<load-configuration-results>
                            <ok/>
                        </load-configuration-results>"""))
        op = self.conf.load(path="test.conf", update=True)
        self.assertEqual(op.tag, "load-configuration-results")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "text")

    def test_config_load_update_merge_overwrite(self):
        self.assertRaises(
            ValueError,
            self.conf.load,
            path="test.jnpr",
            update=True,
            merge=True,
            overwrite=True,
        )

    @patch(builtin_string + ".open")
    def test_config_load_lformat_byext_ValueError(self, mock_open):
        self.conf.rpc.load_config = MagicMock(return_value="rpc_contents")
        self.assertRaises(ValueError, self.conf.load, path="test.jnpr")

    def test_config_load_lset_format_ValueError(self):
        self.conf.rpc.load_config = MagicMock(return_value="rpc_contents")
        self.assertRaises(ValueError,
                          self.conf.load,
                          "test.xml",
                          format="set",
                          overwrite=True)

    @patch(builtin_string + ".open")
    @patch("jnpr.junos.utils.config.etree.XML")
    def test_config_load_path_xml(self, mock_etree, mock_open):
        self.conf.dev.Template = MagicMock()
        mock_etree.return_value = "rpc_contents"
        self.conf.rpc.load_config = MagicMock(
            return_value=mock_etree.return_value)
        self.assertEqual(self.conf.load(path="test.xml"), "rpc_contents")

    @patch(builtin_string + ".open")
    def test_config_load_path_text(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path="test.conf")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "text")

    @patch(builtin_string + ".open")
    def test_config_load_path_set(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path="test.set")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    @patch(builtin_string + ".open")
    def test_config_load_try_load_rpcerror(self, mock_open):
        ex = ConfigLoadError(
            rsp=etree.fromstring(("""<load-configuration-results>
                <rpc-error>
                <error-severity>error</error-severity>
                <error-message>syntax error</error-message>
                </rpc-error>
                </load-configuration-results>""")))
        self.conf.rpc.load_config = MagicMock(side_effect=ex)
        self.assertRaises(ConfigLoadError, self.conf.load, path="config.conf")

    @patch(builtin_string + ".open")
    def test_config_load_try_load_rpctimeouterror(self, mock_open):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.load_config = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.load, path="config.conf")

    @patch(builtin_string + ".open")
    def test_config_try_load_exception(self, mock_open):
        class OtherException(Exception):
            pass

        self.conf.rpc.load_config = MagicMock(side_effect=OtherException())
        self.assertRaises(OtherException, self.conf.load, path="config.conf")

    @patch("jnpr.junos.utils.config.etree.XML")
    def test_config_load_template_path(self, mock_etree):
        self.conf.rpc.load_config = MagicMock()
        self.conf.dev.Template = MagicMock()
        self.conf.load(template_path="test.xml")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "xml")

    def test_config_load_template(self):
        class Temp:
            filename = "abc.xml"
            render = MagicMock(return_value="<test/>")

        self.conf.rpc.load_config = MagicMock()
        self.conf.load(template=Temp)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "xml")

    def test_config_diff_exception(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.diff, 51)
        self.assertRaises(ValueError, self.conf.diff, -1)

    def test_config_lock(self):
        self.conf.rpc.lock_configuration = MagicMock()
        self.assertTrue(self.conf.lock())

    @patch("jnpr.junos.utils.config.JXML.rpc_error")
    def test_config_lock_LockError(self, mock_jxml):
        ex = RpcError(rsp="ok")
        self.conf.rpc.lock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(LockError, self.conf.lock)

    @patch("jnpr.junos.utils.config.JXML.rpc_error")
    def test_config_lock_ConnectClosedError(self, mock_jxml):
        ex = ConnectClosedError(dev=self)
        self.conf.rpc.lock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(ConnectClosedError, self.conf.lock)

    @patch("jnpr.junos.utils.config.JXML.remove_namespaces")
    def test_config_lock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = "test"

        self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(LockError, self.conf.lock)

    def test_config_unlock(self):
        self.conf.rpc.unlock_configuration = MagicMock()
        self.assertTrue(self.conf.unlock())

    @patch("jnpr.junos.utils.config.JXML.rpc_error")
    def test_config_unlock_LockError(self, mock_jxml):
        ex = RpcError(rsp="ok")
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(UnlockError, self.conf.unlock)

    @patch("jnpr.junos.utils.config.JXML.rpc_error")
    def test_config_unlock_ConnectClosedError(self, mock_jxml):
        ex = ConnectClosedError(dev=self)
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(ConnectClosedError, self.conf.unlock)

    @patch("jnpr.junos.utils.config.JXML.remove_namespaces")
    def test_config_unlock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = "test"

        self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(UnlockError, self.conf.unlock)

    def test_config_rollback(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertTrue(self.conf.rollback())

    def test_config_rollback_exception(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.rollback, 51)
        self.assertRaises(ValueError, self.conf.rollback, -1)

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_save(self, mock_exec):
        self.dev.request_save_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue("save"))

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_get_exception(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception)
        self.assertTrue(self.conf.rescue("get") is None)

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_get(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock()
        self.dev.rpc.get_rescue_information.return_value = 1
        self.assertEqual(self.conf.rescue("get", format="xml"), 1)

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_delete(self, mock_exec):
        self.dev.rpc.request_delete_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue("delete"))

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_reload(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock()
        self.dev.rpc.load_configuration.return_value = True
        self.assertTrue(self.conf.rescue("reload"))

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_reload_exception(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock(side_effect=Exception)
        self.assertFalse(self.conf.rescue("reload"))

    @patch("jnpr.junos.Device.execute")
    def test_rescue_action_unsupported_action(self, mock_exec):
        self.assertRaises(ValueError, self.conf.rescue, "abc")

    def test_config_load_lset_from_rexp_xml(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """<snmp><name>iBGP</name></snmp>"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "xml")

    def test_config_load_lset_from_rexp_json(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """{
            "configuration" : {
                "system" : {
                    "services" : {
                        "telnet" : [null]
                    }
                }
            }
        }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "json")

    def test_config_load_lset_from_rexp_set(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """set system domain-name englab.nitin.net"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_delete(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """delete snmp"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_rename(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """rename firewall family inet filter f1 to filter f2"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_insert(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """insert policy-options policy-statement hop term 10 after 9"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_activate(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """activate system services ftp"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_deactivate(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """deactivate system services ftp"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_annotate(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """annotate system \"Annotation test\""""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_copy(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """copy firewall family inet filter f1 to filter f2"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_protect(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """protect system services"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_set_unprotect(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """unprotect system services"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "set")

    def test_config_load_lset_from_rexp_conf(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "text")

    def test_config_load_lset_from_rexp_conf_replace_tag(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """replace:
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["format"],
                         "text")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["action"],
                         "replace")

    def test_config_load_lset_from_rexp_error(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """test>"""
        self.assertRaises(RuntimeError, self.conf.load, conf)

    def test_load_merge_true(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf, merge=True)
        self.assertFalse("action" in self.conf.rpc.load_config.call_args[1])

    def test_commit_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.dev.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.commit)

    def test_commit_check_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.dev.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.commit_check)

    def test_commit_configuration_multi_rpc_error(self):
        self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
        try:
            self.dev.rpc.commit_configuration()
        except Exception as ex:
            self.assertTrue(isinstance(ex, RpcError))
            self.assertEqual(
                ex.message,
                "error: interface-range 'axp' is not defined\n"
                "error: interface-ranges expansion failed",
            )
            self.assertEqual(
                ex.errs,
                [
                    {
                        "source": None,
                        "message": "interface-range 'axp' is not defined",
                        "bad_element": None,
                        "severity": "error",
                        "edit_path": None,
                    },
                    {
                        "source": None,
                        "message": "interface-ranges expansion failed",
                        "bad_element": None,
                        "severity": "error",
                        "edit_path": None,
                    },
                ],
            )

    @patch("jnpr.junos.utils.config.Config.lock")
    @patch("jnpr.junos.utils.config.Config.unlock")
    def test_config_mode_exclusive(self, mock_unlock, mock_lock):
        with Config(self.dev, mode="exclusive") as conf:
            conf.rpc.load_config = MagicMock()
            conf.load("conf", format="set")
        self.assertTrue(mock_lock.called and mock_unlock.called)

    @patch("jnpr.junos.Device.execute")
    def test_config_mode_batch(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode="batch") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(batch=True)

    @patch("jnpr.junos.Device.execute")
    def test_config_mode_private(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode="private") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(private=True)

    @patch("jnpr.junos.Device.execute")
    def test_config_mode_dynamic(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode="dynamic") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(dynamic=True)

    @patch("jnpr.junos.Device.execute")
    def test_config_mode_ephemeral_default(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode="ephemeral") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(ephemeral=True)

    @patch("jnpr.junos.Device.execute")
    def test_config_mode_ephemeral_instance(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        with Config(self.dev, mode="ephemeral",
                    ephemeral_instance="xyz") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(
            ephemeral_instance="xyz")

    def test_config_unsupported_kwargs(self):
        self.dev.rpc.open_configuration = MagicMock()
        try:
            with Config(self.dev, mode="ephemeral", xyz="xyz") as conf:
                conf.load("conf", format="set")
        except Exception as ex:
            self.assertEqual(str(ex),
                             "Unsupported argument provided to Config class")

    @patch("jnpr.junos.Device.execute")
    def test_config_mode_close_configuration_ex(self, mock_exec):
        self.dev.rpc.open_configuration = MagicMock()
        ex = RpcError(rsp="ok")
        ex.message = "Configuration database is not open"
        self.dev.rpc.close_configuration = MagicMock(side_effect=ex)
        try:
            with Config(self.dev, mode="batch") as conf:
                conf.load("conf", format="set")
        except Exception as ex:
            self.assertTrue(isinstance(ex, RpcError))
        self.assertTrue(self.dev.rpc.close_configuration.called)

    def test_config_mode_undefined(self):
        try:
            with Config(self.dev, mode="unknown") as conf:
                conf.load("conf", format="set")
        except Exception as ex:
            self.assertTrue(isinstance(ex, ValueError))

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.utils.config.warnings")
    def test_config_mode_batch_open_configuration_ex(self, mock_warnings,
                                                     mock_exec):
        rpc_xml = """
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>syntax error</error-message>
        </rpc-error>
        """
        rsp = etree.XML(rpc_xml)
        obj = RpcError(rsp=rsp)
        self.dev.rpc.open_configuration = MagicMock(side_effect=obj)
        with Config(self.dev, mode="batch") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(batch=True)

    @patch("jnpr.junos.Device.execute")
    @patch("jnpr.junos.utils.config.warnings")
    def test_config_mode_private_open_configuration_ex(self, mock_warnings,
                                                       mock_exec):
        rpc_xml = """
            <rpc-error>
            <error-severity>warning</error-severity>
            <error-info><bad-element>bgp</bad-element></error-info>
            <error-message>syntax error</error-message>
        </rpc-error>
        """
        rsp = etree.XML(rpc_xml)
        obj = RpcError(rsp=rsp)
        self.dev.rpc.open_configuration = MagicMock(side_effect=obj)
        with Config(self.dev, mode="private") as conf:
            conf.load("conf", format="set")
        self.dev.rpc.open_configuration.assert_called_with(private=True)

    def test__enter__private_exception_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.open_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, Config.__enter__,
                          Config(self.dev, mode="private"))

    def test__enter__private_exception_RpcError(self):
        rpc_xml = """<rpc-error>
            <error-severity>error</error-severity>
            <error-message>syntax error</error-message>
            </rpc-error>"""
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.open_configuration = MagicMock(side_effect=RpcError(
            rsp=rsp))
        self.assertRaises(RpcError, Config.__enter__,
                          Config(self.dev, mode="private"))

    def test__enter__dyanamic_exception_RpcError(self):
        rpc_xml = """<rpc-error>
            <error-severity>error</error-severity>
            <error-message>syntax error</error-message>
            </rpc-error>"""
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.open_configuration = MagicMock(side_effect=RpcError(
            rsp=rsp))
        self.assertRaises(RpcError, Config.__enter__,
                          Config(self.dev, mode="dynamic"))

    def test__enter__batch_exception_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.conf.rpc.open_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, Config.__enter__,
                          Config(self.dev, mode="batch"))

    def test__enter__batch_exception_RpcError(self):
        rpc_xml = """<rpc-error>
            <error-severity>error</error-severity>
            <error-message>syntax error</error-message>
            </rpc-error>"""
        rsp = etree.XML(rpc_xml)
        self.conf.rpc.open_configuration = MagicMock(side_effect=RpcError(
            rsp=rsp))
        self.assertRaises(RpcError, Config.__enter__,
                          Config(self.dev, mode="batch"))

    def test_config_load_url(self):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(url="/var/home/user/golden.conf")
        self.assertEqual(self.conf.rpc.load_config.call_args[1]["url"],
                         "/var/home/user/golden.conf")

    @patch("jnpr.junos.Device.execute")
    def test_load_config_patch(self, mock_exec):
        conf = """[edit system]
            -  host-name pakzds904;
            +  host-name pakzds904_set;
            """
        self.conf.load(conf, format="text", patch=True)
        self.assertEqual(mock_exec.call_args[0][0].tag, "load-configuration")
        self.assertEqual(mock_exec.call_args[0][0].attrib, {
            "format": "text",
            "action": "patch"
        })

    @patch("jnpr.junos.Device.execute")
    def test_load_config_text(self, mock_exec):
        textdata = """policy-options {
            prefix-list TEST1-NETS {
                100.0.0.0/24;
            }
            policy-statement TEST1-NETS {
                term TEST1 {
                    from {
                        prefix-list TEST1-NETS;
                    }
                    then accept;
                }
                term REJECT {
                    then reject;
                }
            }
        }"""
        self.conf.load(textdata, overwrite=True)
        self.assertEqual(mock_exec.call_args[0][0].tag, "load-configuration")
        self.assertEqual(mock_exec.call_args[0][0].getchildren()[0].tag,
                         "configuration-text")
        self.assertEqual(mock_exec.call_args[0][0].attrib, {
            "format": "text",
            "action": "override"
        })

    def _read_file(self, fname):
        fpath = os.path.join(os.path.dirname(__file__), "rpc-reply", fname)
        foo = open(fpath).read()

        # specific to multi rpc error
        if fname == "commit-configuration.xml":
            raw = etree.XML(foo)
            obj = RPCReply(raw)
            obj.parse()
            raise RPCError(etree.XML(foo), errs=obj._errors)

    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:
            return self._read_file(args[0].tag + ".xml")
示例#11
0
class Netconf(object):
    def __init__(self, module):
        self.module = module
        self.device = None
        self.config = None
        self._locked = False

    def _fail(self, msg):
        if self.device:
            if self._locked:
                self.config.unlock()
            self.disconnect()
        self.module.fail_json(msg=msg)

    def connect(self, **kwargs):
        try:
            host = self.module.params['host']
            port = self.module.params['port'] or 830

            user = self.module.params['username']
            passwd = self.module.params['password']
            key_filename = self.module.params['ssh_keyfile']

            self.device = Device(host,
                                 user=user,
                                 passwd=passwd,
                                 port=port,
                                 gather_facts=False,
                                 ssh_private_key_file=key_filename).open()

            self.config = Config(self.device)

        except Exception:
            exc = get_exception()
            self._fail('unable to connect to %s: %s' % (host, str(exc)))

    def run_commands(self, commands, **kwargs):
        response = list()
        fmt = kwargs.get('format') or 'xml'

        for cmd in to_list(commands):
            try:
                resp = self.device.cli(command=cmd, format=fmt)
                response.append(resp)
            except (ValueError, RpcError):
                exc = get_exception()
                self._fail('Unable to get cli output: %s' % str(exc))
            except Exception:
                exc = get_exception()
                self._fail('Uncaught exception - please report: %s' % str(exc))

        return response

    def unlock_config(self):
        try:
            self.config.unlock()
            self._locked = False
        except UnlockError:
            exc = get_exception()
            self.module.log('unable to unlock config: {0}'.format(str(exc)))

    def lock_config(self):
        try:
            self.config.lock()
            self._locked = True
        except LockError:
            exc = get_exception()
            self.module.log('unable to lock config: {0}'.format(str(exc)))

    def check_config(self):
        if not self.config.commit_check():
            self._fail(msg='Commit check failed')

    def commit_config(self, comment=None, confirm=None):
        try:
            kwargs = dict(comment=comment)
            if confirm and confirm > 0:
                kwargs['confirm'] = confirm
            return self.config.commit(**kwargs)
        except CommitError:
            exc = get_exception()
            msg = 'Unable to commit configuration: {0}'.format(str(exc))
            self._fail(msg=msg)

    def load_config(self,
                    candidate,
                    action='replace',
                    comment=None,
                    confirm=None,
                    format='text',
                    commit=True):

        merge = action == 'merge'
        overwrite = action == 'overwrite'

        self.lock_config()

        try:
            self.config.load(candidate,
                             format=format,
                             merge=merge,
                             overwrite=overwrite)
        except ConfigLoadError:
            exc = get_exception()
            msg = 'Unable to load config: {0}'.format(str(exc))
            self._fail(msg=msg)

        diff = self.config.diff()
        self.check_config()
        if commit and diff:
            self.commit_config(comment=comment, confirm=confirm)

        self.unlock_config()

        return diff

    def rollback_config(self, identifier, commit=True, comment=None):

        self.lock_config()

        try:
            result = self.config.rollback(identifier)
        except Exception:
            exc = get_exception()
            msg = 'Unable to rollback config: {0}'.format(str(exc))
            self._fail(msg=msg)

        diff = self.config.diff()
        if commit:
            self.commit_config(comment=comment)

        self.unlock_config()
        return diff

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

    def get_facts(self, refresh=True):
        if refresh:
            self.device.facts_refresh()
        return self.device.facts

    def get_config(self, config_format="text"):
        if config_format not in ['text', 'set', 'xml']:
            msg = 'invalid config format... must be one of xml, text, set'
            self._fail(msg=msg)

        ele = self.rpc('get_configuration', format=config_format)
        if config_format in ['text', 'set']:
            return str(ele.text).strip()
        elif config_format == "xml":
            return ele

    def rpc(self, name, format='xml', **kwargs):
        meth = getattr(self.device.rpc, name)
        reply = meth({'format': format}, **kwargs)
        return reply
示例#12
0
print("Open connection ...")
dev = Device(host=device, user=user, password=password, gather_facts=False)
dev.open()

print("Load config  ...")
conf = Config(dev)

print("Locking config ...")
conf.lock()

print("Rollback config ...")
conf.rollback()

data = 'set interfaces gr-0/0/0 description "Some description sample standalone for gr-0/0/0"'
conf.load(data, format='set')  # syntax error raises exception

print("Check  ...")
conf.commit_check()

print("Commit  ...")
conf.commit()

print("Unlocking config ...")
conf.unlock()

print("Close connection ... ")
dev.close()

print("DONE")
示例#13
0
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
import yaml
#testing gitbranch
#dummy changes only in master branch

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

data = yaml.load(open('protocol_data.yml'))

cu = Config(dev)

cu.load(template_path='protocol_temp.j2', template_vars=data, format='text')
cu.pdiff()
if cu.commit_check():
    cu.commit()
else:
    cu.rollback()

dev.close()
示例#14
0
class TestConfig(unittest.TestCase):

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

    def test_config_constructor(self):
        self.assertTrue(isinstance(self.conf._dev, Device))

    def test_config_confirm_true(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(confirmed=True)

    def test_config_commit_confirm(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(confirm=10)
        self.conf.rpc.commit_configuration\
            .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True})

    def test_config_commit_comment(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(comment='Test')
        self.conf.rpc.commit_configuration.assert_called_with(log='Test')

    def test_config_commit_sync(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(sync=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(synchronize=True)

    def test_config_commit_force_sync(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(force_sync=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(**{'synchronize': True, 'force-synchronize': True})

    def test_config_commit_timeout(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(timeout=60)
        self.conf.rpc.commit_configuration\
            .assert_called_with(dev_timeout=60)

    def test_config_commit_full(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.commit(full=True)
        self.conf.rpc.commit_configuration\
            .assert_called_with(full=True)

    def test_config_commit_detail(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.rpc.commit_configuration.return_value = '<mockdetail/>'
        self.assertEqual('<mockdetail/>', self.conf.commit(detail=True))
        self.conf.rpc.commit_configuration\
            .assert_called_with({'detail': 'detail'})

    def test_config_commit_combination(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.conf.rpc.commit_configuration.return_value = '<moredetail/>'
        self.assertEqual('<moredetail/>', self.conf.commit(detail=True, force_sync=True, full=True))
        self.conf.rpc.commit_configuration\
            .assert_called_with({'detail': 'detail'},
                                **{'synchronize': True, 'full': True, 'force-synchronize': True})

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_commit_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.commit_configuration = \
            MagicMock(side_effect=MyException)
        self.assertRaises(AttributeError, self.conf.commit)

    def test_config_commit_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit)

    def test_commit_check(self):
        self.conf.rpc.commit_configuration = MagicMock()
        self.assertTrue(self.conf.commit_check())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_commit_check_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException)
        # with self.assertRaises(AttributeError):
        self.conf.commit_check()

    def test_config_commit_check_exception_RpcError(self):
        ex = RpcError(rsp='ok')
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertTrue(self.conf.commit_check())
        import xml.etree.ElementTree as ET
        xmldata = """<data><company name="Juniper">
            <code>pyez</code>
            <year>2013</year>
            </company></data>"""
        root = ET.fromstring(xmldata)
        el = root.find('company')
        ex = RpcError(rsp=el)
        self.conf.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(CommitError, self.conf.commit_check)

    def test_config_diff(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.conf.diff()
        self.conf.rpc.get_configuration.\
            assert_called_with(
                {'compare': 'rollback', 'rollback': '0', 'format': 'text'})

    def test_config_pdiff(self):
        self.conf.diff = MagicMock(return_value='Stuff')
        self.conf.pdiff()
        self.conf.diff.assert_called_once_with(0)

    def test_config_load(self):
        self.assertRaises(RuntimeError, self.conf.load)

    def test_config_load_vargs_len(self):
        self.assertRaises(RuntimeError, self.conf.load,
                          'test.xml')

    def test_config_load_len_with_format_set(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertEqual(self.conf.load('test.xml', format='set'),
                         'rpc_contents')

    def test_config_load_len_with_format_xml(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        xmldata = """<snmp>
          <community>
            <name>iBGP</name>
          </community>
        </snmp>"""

        self.assertEqual(self.conf.load(xmldata, format='xml'),
                         'rpc_contents')

    @patch('__builtin__.open')
    def test_config_load_lformat_byext_ValueError(self, mock_open):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load, path='test.jnpr')

    def test_config_load_lset_format_ValueError(self):
        self.conf.rpc.load_config = \
            MagicMock(return_value='rpc_contents')
        self.assertRaises(ValueError, self.conf.load,
                          'test.xml', format='set', overwrite=True)

    @patch('__builtin__.open')
    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_path_xml(self, mock_etree, mock_open):
        self.conf.dev.Template = MagicMock()
        mock_etree.return_value = 'rpc_contents'
        self.conf.rpc.load_config = \
            MagicMock(return_value=mock_etree.return_value)
        self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents')

    @patch('__builtin__.open')
    def test_config_load_path_text(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.conf')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    @patch('__builtin__.open')
    def test_config_load_path_set(self, mock_open):
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(path='test.set')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    @patch('__builtin__.open')
    def test_config_load_try_load_rpcerror(self, mock_open):
        ex = ConfigLoadError(
            rsp=etree.fromstring((
                """<load-configuration-results>
                <rpc-error>
                <error-severity>error</error-severity>
                <error-message>syntax error</error-message>
                </rpc-error>
                </load-configuration-results>""")))
        self.conf.rpc.load_config = MagicMock(side_effect=ex)
        self.assertRaises(ConfigLoadError, self.conf.load, path='config.conf')

    @patch('__builtin__.open')
    def test_config_try_load_exception(self, mock_open):
        class OtherException(Exception):
            pass
        self.conf.rpc.load_config = MagicMock(side_effect=OtherException())
        self.assertRaises(OtherException, self.conf.load, path='config.conf')

    @patch('jnpr.junos.utils.config.etree.XML')
    def test_config_load_template_path(self, mock_etree):
        self.conf.rpc.load_config = MagicMock()
        self.conf.dev.Template = MagicMock()
        self.conf.load(template_path='test.xml')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_load_template(self):
        class Temp:
            filename = 'abc.xml'
            render = MagicMock(return_value='<test/>')
        self.conf.rpc.load_config = MagicMock()
        self.conf.load(template=Temp)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_diff_exception(self):
        self.conf.rpc.get_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.diff, 51)
        self.assertRaises(ValueError, self.conf.diff, -1)

    def test_config_lock(self):
        self.conf.rpc.lock_configuration = MagicMock()
        self.assertTrue(self.conf.lock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_lock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.lock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(LockError, self.conf.lock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_lock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(LockError, self.conf.lock)

    def test_config_unlock(self):
        self.conf.rpc.unlock_configuration = MagicMock()
        self.assertTrue(self.conf.unlock())

    @patch('jnpr.junos.utils.config.JXML.rpc_error')
    def test_config_unlock_LockError(self, mock_jxml):
        ex = RpcError(rsp='ok')
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex)
        self.assertRaises(UnlockError, self.conf.unlock)

    @patch('jnpr.junos.utils.config.JXML.remove_namespaces')
    def test_config_unlock_exception(self, mock_jxml):
        class MyException(Exception):
            xml = 'test'
        self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException)
        self.assertRaises(UnlockError, self.conf.unlock)

    def test_config_rollback(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertTrue(self.conf.rollback())

    def test_config_rollback_exception(self):
        self.conf.rpc.load_configuration = MagicMock()
        self.assertRaises(ValueError, self.conf.rollback, 51)
        self.assertRaises(ValueError, self.conf.rollback, -1)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_save(self, mock_exec):
        self.dev.request_save_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue('save'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_get_exception(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception)
        self.assertTrue(self.conf.rescue('get') is None)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_get(self, mock_exec):
        self.dev.rpc.get_rescue_information = MagicMock()
        self.dev.rpc.get_rescue_information.return_value = 1
        self.assertEqual(self.conf.rescue('get', format='xml'), 1)

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_delete(self, mock_exec):
        self.dev.rpc.request_delete_rescue_configuration = MagicMock()
        self.assertTrue(self.conf.rescue('delete'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_reload(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock()
        self.dev.rpc.load_configuration.return_value = True
        self.assertTrue(self.conf.rescue('reload'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_reload_exception(self, mock_exec):
        self.dev.rpc.load_configuration = MagicMock(side_effect=Exception)
        self.assertFalse(self.conf.rescue('reload'))

    @patch('jnpr.junos.Device.execute')
    def test_rescue_action_unsupported_action(self, mock_exec):
        self.assertRaises(ValueError, self.conf.rescue, 'abc')

    def test_config_load_lset_from_rexp_xml(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """<snmp><name>iBGP</name></snmp>"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'xml')

    def test_config_load_lset_from_rexp_set(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """set system domain-name englab.nitin.net"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_lset_from_rexp_set_delete(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """delete snmp"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'set')

    def test_config_load_lset_from_rexp_conf(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')

    def test_config_load_lset_from_rexp_conf_replace_tag(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """replace:
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf)
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'],
                         'text')
        self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'],
                         'replace')

    def test_config_load_lset_from_rexp_error(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """nitin>"""
        self.assertRaises(RuntimeError, self.conf.load, conf)

    def test_load_merge_true(self):
        self.conf.rpc.load_config = MagicMock()
        conf = """
            snmp {
                location USA;
                community iBGP {
                authorization read-only;
            }
            }"""
        self.conf.load(conf, merge=True)
        self.assertFalse('action' in self.conf.rpc.load_config.call_args[1])

    def test_commit_RpcTimeoutError(self):
        ex = RpcTimeoutError(self.dev, None, 10)
        self.dev.rpc.commit_configuration = MagicMock(side_effect=ex)
        self.assertRaises(RpcTimeoutError, self.conf.commit)
示例#15
0
class Netconf(object):

    def __init__(self, module):
        self.module = module
        self.device = None
        self.config = None
        self._locked = False

    def _fail(self, msg):
        if self.device:
            if self._locked:
                self.config.unlock()
            self.disconnect()
        self.module.fail_json(msg=msg)

    def connect(self, **kwargs):
        try:
            host = self.module.params['host']
            port = self.module.params['port'] or 830

            user = self.module.params['username']
            passwd = self.module.params['password']
            key_filename = self.module.params['ssh_keyfile']

            self.device = Device(host, user=user, passwd=passwd, port=port,
                    gather_facts=False, ssh_private_key_file=key_filename).open()

            self.config = Config(self.device)

        except Exception:
            exc = get_exception()
            self._fail('unable to connect to %s: %s' % (host, str(exc)))

    def run_commands(self, commands, **kwargs):
        response = list()
        fmt = kwargs.get('format') or 'xml'

        for cmd in to_list(commands):
            try:
                resp = self.device.cli(command=cmd, format=fmt)
                response.append(resp)
            except (ValueError, RpcError):
                exc = get_exception()
                self._fail('Unable to get cli output: %s' % str(exc))
            except Exception:
                exc = get_exception()
                self._fail('Uncaught exception - please report: %s' % str(exc))

        return response

    def unlock_config(self):
        try:
            self.config.unlock()
            self._locked = False
        except UnlockError:
            exc = get_exception()
            self.module.log('unable to unlock config: {0}'.format(str(exc)))

    def lock_config(self):
        try:
            self.config.lock()
            self._locked = True
        except LockError:
            exc = get_exception()
            self.module.log('unable to lock config: {0}'.format(str(exc)))

    def check_config(self):
        if not self.config.commit_check():
            self._fail(msg='Commit check failed')

    def commit_config(self, comment=None, confirm=None):
        try:
            kwargs = dict(comment=comment)
            if confirm and confirm > 0:
                kwargs['confirm'] = confirm
            return self.config.commit(**kwargs)
        except CommitError:
            exc = get_exception()
            msg = 'Unable to commit configuration: {0}'.format(str(exc))
            self._fail(msg=msg)

    def load_config(self, candidate, action='replace', comment=None,
            confirm=None, format='text', commit=True):

        merge = action == 'merge'
        overwrite = action == 'overwrite'

        self.lock_config()

        try:
            self.config.load(candidate, format=format, merge=merge,
                    overwrite=overwrite)
        except ConfigLoadError:
            exc = get_exception()
            msg = 'Unable to load config: {0}'.format(str(exc))
            self._fail(msg=msg)

        diff = self.config.diff()
        self.check_config()
        if commit and diff:
            self.commit_config(comment=comment, confirm=confirm)

        self.unlock_config()

        return diff

    def rollback_config(self, identifier, commit=True, comment=None):

        self.lock_config()

        try:
            result = self.config.rollback(identifier)
        except Exception:
            exc = get_exception()
            msg = 'Unable to rollback config: {0}'.format(str(exc))
            self._fail(msg=msg)

        diff = self.config.diff()
        if commit:
            self.commit_config(comment=comment)

        self.unlock_config()
        return diff

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

    def get_facts(self, refresh=True):
        if refresh:
            self.device.facts_refresh()
        return self.device.facts

    def get_config(self, config_format="text"):
        if config_format not in ['text', 'set', 'xml']:
            msg = 'invalid config format... must be one of xml, text, set'
            self._fail(msg=msg)

        ele = self.rpc('get_configuration', format=config_format)
        if config_format in ['text', 'set']:
           return str(ele.text).strip()
        elif config_format == "xml":
            return ele

    def rpc(self, name, format='xml', **kwargs):
        meth = getattr(self.device.rpc, name)
        reply = meth({'format': format}, **kwargs)
        return reply
示例#16
0
文件: junos.py 项目: likewg/DevOps
class Netconf(object):

    def __init__(self):
        if not HAS_PYEZ:
            raise NetworkError(
                msg='junos-eznc >= 1.2.2 is required but does not appear to be installed.  '
                'It can be installed using `pip install junos-eznc`'
            )
        if not HAS_JXMLEASE:
            raise NetworkError(
                msg='jxmlease is required but does not appear to be installed.  '
                'It can be installed using `pip install jxmlease`'
            )
        self.device = None
        self.config = None
        self._locked = False
        self._connected = False
        self.default_output = 'xml'

    def raise_exc(self, msg):
        if self.device:
            if self._locked:
                self.config.unlock()
            self.disconnect()
        raise NetworkError(msg)

    def connect(self, params, **kwargs):
        host = params['host']

        kwargs = dict()
        kwargs['port'] = params.get('port') or 830

        kwargs['user'] = params['username']

        if params['password']:
            kwargs['passwd'] = params['password']

        if params['ssh_keyfile']:
            kwargs['ssh_private_key_file'] = params['ssh_keyfile']

        kwargs['gather_facts'] = False

        try:
            self.device = Device(host, **kwargs)
            self.device.open()
        except ConnectError:
            exc = get_exception()
            self.raise_exc('unable to connect to %s: %s' % (host, str(exc)))

        self.config = Config(self.device)
        self._connected = True

    def disconnect(self):
        try:
            self.device.close()
        except AttributeError:
            pass
        self._connected = False

    ### Command methods ###

    def run_commands(self, commands):
        responses = list()

        for cmd in commands:
            meth = getattr(self, cmd.args.get('command_type'))
            responses.append(meth(str(cmd), output=cmd.output))

        for index, cmd in enumerate(commands):
            if cmd.output == 'xml':
                responses[index] = xml_to_json(responses[index])
            elif cmd.args.get('command_type') == 'rpc':
                responses[index] = str(responses[index].text).strip()
            elif 'RpcError' in responses[index]:
                raise NetworkError(responses[index])


        return responses

    def cli(self, commands, output='xml'):
        '''Send commands to the device.'''
        try:
            return self.device.cli(commands, format=output, warning=False)
        except (ValueError, RpcError):
            exc = get_exception()
            self.raise_exc('Unable to get cli output: %s' % str(exc))

    def rpc(self, command, output='xml'):
        name, kwargs = rpc_args(command)
        meth = getattr(self.device.rpc, name)
        reply = meth({'format': output}, **kwargs)
        return reply

    ### Config methods ###

    def get_config(self, config_format="text"):
        if config_format not in SUPPORTED_CONFIG_FORMATS:
            self.raise_exc(msg='invalid config format.  Valid options are '
                               '%s' % ', '.join(SUPPORTED_CONFIG_FORMATS))

        ele = self.rpc('get_configuration', output=config_format)

        if config_format == 'text':
            return unicode(ele.text).strip()
        else:
            return ele

    def load_config(self, config, commit=False, replace=False, confirm=None,
                    comment=None, config_format='text', overwrite=False):

        if all([replace, overwrite]):
            self.raise_exc('setting both replace and overwrite to True is invalid')

        if replace:
            merge = False
            overwrite = False
        elif overwrite:
            merge = True
            overwrite = False
        else:
            merge = True
            overwrite = False

        if overwrite and config_format == 'set':
            self.raise_exc('replace cannot be True when config_format is `set`')

        self.lock_config()

        try:
            candidate = '\n'.join(config)
            self.config.load(candidate, format=config_format, merge=merge,
                             overwrite=overwrite)

        except ConfigLoadError:
            exc = get_exception()
            self.raise_exc('Unable to load config: %s' % str(exc))

        diff = self.config.diff()

        self.check_config()

        if all((commit, diff)):
            self.commit_config(comment=comment, confirm=confirm)

        self.unlock_config()

        return diff

    def save_config(self):
        raise NotImplementedError

    ### end of Config ###

    def get_facts(self, refresh=True):
        if refresh:
            self.device.facts_refresh()
        return self.device.facts

    def unlock_config(self):
        try:
            self.config.unlock()
            self._locked = False
        except UnlockError:
            exc = get_exception()
            raise NetworkError('unable to unlock config: %s' % str(exc))

    def lock_config(self):
        try:
            self.config.lock()
            self._locked = True
        except LockError:
            exc = get_exception()
            raise NetworkError('unable to lock config: %s' % str(exc))

    def check_config(self):
        if not self.config.commit_check():
            self.raise_exc(msg='Commit check failed')

    def commit_config(self, comment=None, confirm=None):
        try:
            kwargs = dict(comment=comment)
            if confirm and confirm > 0:
                kwargs['confirm'] = confirm
            return self.config.commit(**kwargs)
        except CommitError:
            exc = get_exception()
            raise NetworkError('unable to commit config: %s' % str(exc))

    def confirm_commit(self, checkonly=False):
        try:
            resp = self.rpc('get_commit_information')
            needs_confirm = 'commit confirmed, rollback' in resp[0][4].text
            if checkonly:
                return needs_confirm
            return self.commit_config()
        except IndexError:
            # if there is no comment tag, the system is not in a commit
            # confirmed state so just return
            pass

    def rollback_config(self, identifier, commit=True, comment=None):

        self.lock_config()

        try:
            self.config.rollback(identifier)
        except ValueError:
            exc = get_exception()
            self.raise_exc('Unable to rollback config: $s' % str(exc))

        diff = self.config.diff()
        if commit:
            self.commit_config(comment=comment)

        self.unlock_config()
        return diff
示例#17
0
文件: rcli.py 项目: telnik/jCnC
	def run(self):
		# import pdb; pdb.set_trace() # dbg
		dev = Device(host=self.host, user=self.user, password=self.passw)
		try:
			dev.open(auto_probe=7)
		except:
			self.result += "Could not connect to host\n"
			return

		if not self.mode:
			self.result += "A mode of operation must be specified"
		elif self.mode == "configure":
			confc = Config(dev)
			if self.action == "commit":
				self.result += confc.commit(confirm=True, comment="Commited " + str( datetime.datetime.now() ) + " by jCnC")
			elif self.action == "commit_check":
				if confc.commit_check():
					self.result += "Commit Check Succeeds"
				else:
					self.result += "Commit Check Failed"
			elif self.action == "diff":
				x = int(self.param)
				self.result += confc.diff() #self.param)
			elif self.action == "load":
				self.result += confc.load(path=param, overwrite=True, format='conf')
			elif self.action == "lock":
				self.result += confc.lock()
			elif self.action == "rescue":
				self.result += confc.rescue(param)
			elif self.action == "rollback":
				self.result += confc.rollback(param)
			elif self.action == "save":
				shell = self.start_shell()
				stdin, stdout, stderr = shell.exec_command("cli show configuration | cat")
				config = ""
				for line in stdout.readlines():
					self.result += line
					config += line
				## check for host dir, create if not found
				hostpath = self.host
				if not os.path.exists(hostpath):
					os.makedirs(hostpath)
				hostpath += "/configuration"
				## copy file into directory
				with open(hostpath, 'w') as output:
					output.write(config)
				shell.exec_command("rm /tmp/configuration\n")
				shell.close
			elif self.action == "unlock":
				self.result += confc.unlock()
			else:
				self.result += "Configuration Action not found"
		elif self.mode == "software":
			softw = SW(dev)
			if self.action == "install":
				hash = str('')
				with open(param+'.md5') as hashfile:
					hash = hashfile.read()
				hashfile.closed()
				self.action += softw.install(param, remote_path='/var/tmp', progress=dev, validate=False, checksum=hash, cleanfs=False, no_copy=False, timout=1800) 
			elif action == "rollback":
				self.action += softw.rollback()
		elif self.mode == "cli":
			shell = self.start_shell()
			if self.action == "terminal":
				stdin, stdout, stderr = shell.exec_command("cli")
				stdin.write(self.param + '\n')
				stdin.write("exit\n")
				stdin.flush()
				for line in stdout.readlines():
					self.result += line 
			elif self.action == "file":
				self.result += "\n"
				stdin, stdout, stderr = shell.exec_command("cli")
				cfile = open(self.param, 'r')
				for line in cfile:
					stdin.write(line + '\n')
				stdin.write("exit\n")
				data = stdout.readlines()
				for line in data:
					self.result += "\n" + line
			shell.close()
		elif self.mode == "info":
			shell = self.start_shell()
			if self.action == "alarms":
				stdin, stdout, stderr = shell.exec_command("cli show chassis alarms")
				data = stdout.readlines()
				for line in data:
					self.result += line
			elif self.action == "active_ports":
				stdin, stdout, stderr = shell.exec_command('cli show interfaces terse | grep -v  "\.0" | grep -v down')
				data = stdout.readlines()
				for line in data:
					self.result += line
			elif self.action == "inactive_ports":
				stdin, stdout, stderr = shell.exec_command('cli show interfaces terse | grep -v  "\.0" | grep down')
				data = stdout.readlines()
				for line in data:
					self.result += line
			else:
				self.result += "Information Action not found"
			shell.close()
		else:
			self.result = "Operation Mode not found"

		dev.close()
		self.result += "\n"