def testGetLeafSpineFromPod(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPodSpineLeaf(l3ClosMediation) leafSpineDict = l3ClosMediation.getLeafSpineFromPod(pod) self.assertEqual(2, len(leafSpineDict['leafs'])) self.assertEqual(2, len(leafSpineDict['spines']))
def testProcessTopologyNoPodFound(self): l3ClosMediation = L3ClosMediation(self.conf) with self.assertRaises(ValueError) as ve: l3ClosMediation.processTopology("anyName") error = ve.exception.message self.assertEqual(1, error.count('NoResultFound'))
def testCreateLinks(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPodSpineLeaf(l3ClosMediation) ''' [{ "s_name" : "spine-01", "s_port" : "et-0/0/0", "l_name" : "leaf-01", "l_port" : "et-0/0/48" }, { "s_name" : "spine-01", "s_port" : "et-0/0/1", "l_name" : "leaf-02", "l_port" : "et-0/0/48" }, { "s_name" : "spine-02", "s_port" : "et-0/0/0", "l_name" : "leaf-01", "l_port" : "et-0/0/49" }, { "s_name" : "spine-02", "s_port" : "et-0/0/1", "l_name" : "leaf-02", "l_port" : "et-0/0/49" }] ''' linkString = u'[{ "s_name" : "spine-01", "s_port" : "et-0/0/0", "l_name" : "leaf-01", "l_port" : "et-0/0/48" }, { "s_name" : "spine-01", "s_port" : "et-0/0/1", "l_name" : "leaf-02", "l_port" : "et-0/0/48" }, { "s_name" : "spine-02", "s_port" : "et-0/0/0", "l_name" : "leaf-01", "l_port" : "et-0/0/49" }, { "s_name" : "spine-02", "s_port" : "et-0/0/1", "l_name" : "leaf-02", "l_port" : "et-0/0/49" }]' l3ClosMediation.createLinkBetweenIFDs(pod, json.loads(linkString)) # force close current session and get new session to make sure merge and flush took place properly podId = pod.id l3ClosMediation.dao.Session.remove() session = l3ClosMediation.dao.Session() spine01Port0 = session.query(InterfaceDefinition).join(Device).filter( InterfaceDefinition.name == 'et-0/0/0').filter( Device.name == 'spine-01').filter( Device.pod_id == podId).one() self.assertIsNotNone(spine01Port0.peer) self.assertEqual('et-0/0/48', spine01Port0.peer.name) self.assertEqual('leaf-01', spine01Port0.peer.device.name) spine02Port1 = session.query(InterfaceDefinition).join(Device).filter( InterfaceDefinition.name == 'et-0/0/1').filter( Device.name == 'spine-02').filter( Device.pod_id == podId).one() self.assertIsNotNone(spine02Port1.peer) self.assertEqual('et-0/0/49', spine02Port1.peer.name) self.assertEqual('leaf-02', spine02Port1.peer.device.name)
def testProcessTopology(self): l3ClosMediation = L3ClosMediation(self.conf) podDict = { "hostOrVmCountPerLeaf": 100, "leafDeviceType": "QFX5100-48S", "spineAS": 100, "spineDeviceType": "QFX5100-24Q", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200, "inventory": "inventoryLabLeafSpine.json" } l3ClosMediation.dao.createObjects([Pod('pod1', **podDict)]) l3ClosMediation = flexmock(l3ClosMediation) l3ClosMediation.should_receive('createSpineIFDs').once() l3ClosMediation.should_receive('createLeafIFDs').once() l3ClosMediation.should_receive('createLinkBetweenIFDs').once() l3ClosMediation.should_receive('allocateResource').once() self.assertEqual(True, l3ClosMediation.processTopology('pod1'))
def testCreateLeafGenericConfig(self): self._conf['snmpTrap'] = { 'openclos_trap_group': { 'port': 20162, 'target': '5.6.7.8' } } self._conf['deviceFamily']['ex4300-24p'] = { "uplinkPorts": 'et-0/1/[0-3]', "downlinkPorts": 'ge-0/0/[0-23]' } self._conf['deploymentMode'] = {'ztpStaged': True} self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao) self.createPodSpineLeaf() with self._dao.getReadSession() as session: pod = session.query(Pod).one() pod.outOfBandGateway = '10.0.0.254' pod.outOfBandAddressList = '10.0.10.5/32' leafSettings = self.l3ClosMediation._createLeafGenericConfigsFor2Stage( session, pod) self.assertTrue(1, len(leafSettings)) configlet = leafSettings[0].config self.assertTrue('' != configlet) #print configlet self.assertTrue('trap-group openclos_trap_group' in configlet) self.assertEquals(1, configlet.count('static')) self.assertEquals(2, configlet.count('route'))
def testAllocateInterconnect(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPodSpineLeafLink(l3ClosMediation) session = l3ClosMediation.dao.Session() leafSpineDict = l3ClosMediation.getLeafSpineFromPod(pod) l3ClosMediation.allocateInterconnect('192.168.0.0', leafSpineDict['spines'], leafSpineDict['leafs']) self.assertEqual(8, len(l3ClosMediation.dao.getAll(InterfaceLogical))) ifl = session.query(InterfaceLogical).join(Device).filter( InterfaceLogical.name == 'et-0/0/0.0').filter( Device.name == 'spine-01').filter( Device.pod_id == pod.id).one() belowIfd = session.query(InterfaceDefinition).filter( InterfaceDefinition.id == ifl.layer_below_id).one() self.assertEqual('et-0/0/0', belowIfd.name) self.assertEqual('192.168.0.0/31', ifl.ipaddress) ifl = session.query(InterfaceLogical).join(Device).filter( InterfaceLogical.name == 'et-0/0/48.0').filter( Device.name == 'leaf-01').filter( Device.pod_id == pod.id).one() belowIfd = session.query(InterfaceDefinition).filter( InterfaceDefinition.id == ifl.layer_below_id).one() self.assertEqual('et-0/0/48', belowIfd.name) self.assertEqual('192.168.0.1/31', ifl.ipaddress)
def testInitWithTemplate(self): from jinja2 import TemplateNotFound l3ClosMediation = L3ClosMediation(self.conf) self.assertIsNotNone( l3ClosMediation.templateEnv.get_template('protocolBgpLldp.txt')) with self.assertRaises(TemplateNotFound) as e: l3ClosMediation.templateEnv.get_template('unknown-template') self.assertTrue('unknown-template' in e.exception.message)
def testCablingPlanAndDeviceConfig(self): self._conf['DOT'] = { 'ranksep': '5 equally', 'colors': ['red', 'green', 'blue'] } self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao) pod = self.createPodSpineLeaf() self.assertEqual(True, self.l3ClosMediation.createCablingPlan(pod.id)) self.assertEqual(True, self.l3ClosMediation.createDeviceConfig(pod.id))
def createConfigFilesForDevices(self): ''' Create configuration for each leaf and spine in IP Fabric ''' l3ClosMediation = L3ClosMediation() pods = l3ClosMediation.loadClosDefinition() l3ClosMediation.processFabric('anotherPod', pods['anotherPod'], reCreateFabric=True)
def createConfigFilesForDevices(self): ''' Create configuration for each leaf and spine in IP Fabric ''' l3ClosMediation = L3ClosMediation() pods = l3ClosMediation.loadClosDefinition() pod = l3ClosMediation.createPod('anotherPod', pods['anotherPod']) l3ClosMediation.createCablingPlan(pod.id) l3ClosMediation.createDeviceConfig(pod.id) global generatedDhcpConf generatedDhcpConf = generatedDhcpConf.replace('<pod id>', pod.id) generatedDhcpConf = generatedDhcpConf.replace('<pod name>', pod.name)
def testUpdatePod(self): l3ClosMediation = L3ClosMediation(self.conf) session = l3ClosMediation.dao.Session() pod = self.createPodWithoutInventory(l3ClosMediation) podDict = {"spineAS": 101} inventoryDict = {"spines" : [{ "name" : "spine-11", "mac_address" : "aa:bb:cc:dd:ee:b1", "mgmt_ip" : "172.32.32.201/24" }], \ "leafs" : [{ "name" : "leaf-11", "mac_address" : "aa:bb:cc:dd:ee:a1", "mgmt_ip" : "172.32.32.101/24" }]} l3ClosMediation.updatePod(pod.id, podDict, inventoryDict) self.assertEqual(2, session.query(Device).count()) self.assertEqual(101, pod.spineAS)
def testCreatePolicyOptionSpine(self): l3ClosMediation = L3ClosMediation(self.conf) device = Device("test", "QFX5100-24Q", "user", "pwd", "spine", "mac", "mgmtIp", self.createPod(l3ClosMediation)) device.pod.allocatedIrbBlock = '10.0.0.0/28' device.pod.allocatedLoopbackBlock = '11.0.0.0/28' configlet = l3ClosMediation.createPolicyOption(device) self.assertTrue('irb_in' not in configlet and '10.0.0.0/28' in configlet) self.assertTrue('lo0_in' not in configlet and '11.0.0.0/28' in configlet) self.assertTrue('lo0_out' not in configlet) self.assertTrue('irb_out' not in configlet)
def testAllocateAsNumber(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPodSpineLeafLink(l3ClosMediation) session = l3ClosMediation.dao.Session() leafSpineDict = l3ClosMediation.getLeafSpineFromPod(pod) l3ClosMediation.allocateAsNumber(100, 200, leafSpineDict['spines'], leafSpineDict['leafs']) self.assertEqual( 100, session.query(Device).filter(Device.role == 'spine').all()[0].asn) self.assertEqual( 201, session.query(Device).filter(Device.role == 'leaf').all()[1].asn)
def testCreateAccessInterfaceEx4300(self): self._conf['deviceFamily']['ex4300-48p'] = { "uplinkPorts": 'et-0/0/[48-51]', "downlinkPorts": 'ge-0/0/[0-47]' } self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao) with self._dao.getReadSession() as session: from test_model import createPod pod = createPod('test', session) device = Device("test", "ex4300-48p", "user", "pwd", "leaf", "mac", "mgmtIp", pod) configlet = self.l3ClosMediation._createAccessPortInterfaces( session, device) self.assertEquals(48, configlet.count('family ethernet-switching')) self.assertTrue('ge-0/0/0' in configlet) self.assertTrue('ge-0/0/47' in configlet)
def testGetSnmpTrapTargetsWithStagedZtp(self): self._conf['snmpTrap'] = { 'openclos_trap_group': { 'port': 20162, 'target': '5.6.7.8' } } self._conf['deploymentMode'] = {'ztpStaged': True} self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao) with self._dao.getReadSession() as session: self.assertEqual( 1, len(self.l3ClosMediation._getSnmpTrapTargets(session))) self.assertEqual( '5.6.7.8', self.l3ClosMediation._getSnmpTrapTargets(session)[0])
def testCreateSnmpTrapAndEventLeafNoStagedZtp(self): self._conf['snmpTrap'] = { 'openclos_trap_group': { 'port': 20162, 'target': '1.2.3.4' } } self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao) self.createTrapGroupsInDb(self._dao) device = Device("test", "qfx5100-48s-6q", "user", "pwd", "leaf", "mac", "mgmtIp", None) with self._dao.getReadSession() as session: configlet = self.l3ClosMediation._createSnmpTrapAndEvent( session, device) self.assertEqual('', configlet)
def testCreatePolicyOptionLeaf(self): l3ClosMediation = L3ClosMediation(self.conf) device = Device("test", "QFX5100-48S", "user", "pwd", "leaf", "mac", "mgmtIp", self.createPod(l3ClosMediation)) device.pod.allocatedIrbBlock = '10.0.0.0/28' device.pod.allocatedLoopbackBlock = '11.0.0.0/28' flexmock(l3ClosMediation.dao.Session).should_receive( 'query.join.filter.filter.one').and_return( InterfaceLogical("test", device, '12.0.0.0/28')) configlet = l3ClosMediation.createPolicyOption(device) self.assertTrue('irb_in' not in configlet and '10.0.0.0/28' in configlet) self.assertTrue('lo0_in' not in configlet and '11.0.0.0/28' in configlet) self.assertTrue('lo0_out' not in configlet and '12.0.0.0/28' in configlet) self.assertTrue('irb_out' not in configlet)
def testUpdatePodInvalidId(self): podDict = { "hostOrVmCountPerLeaf": 254, "leafDeviceType": "QFX5100-48S", "spineAS": 100, "spineDeviceType": "QFX5100-24Q", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200 } l3ClosMediation = L3ClosMediation(self.conf) with self.assertRaises(ValueError) as ve: l3ClosMediation.updatePod("invalid_id", podDict, None)
def testIsRecreateFabricFalse(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPod(l3ClosMediation) podDict = { "hostOrVmCountPerLeaf": 100, "leafDeviceType": "QFX5100-48S", "spineAS": 100, "spineDeviceType": "QFX5100-24Q", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200 } self.assertEqual(False, l3ClosMediation.isRecreateFabric(pod, podDict))
def setUp(self): self._conf = {} self._conf['outputDir'] = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'out') self._conf['deviceFamily'] = { "qfx5100-24q-2p": { "ports": 'et-0/0/[0-23]' }, "qfx5100-48s-6q": { "uplinkPorts": 'et-0/0/[48-53]', "downlinkPorts": 'xe-0/0/[0-47]' }, "ex4300-24p": { "uplinkPorts": 'et-0/1/[0-3]', "downlinkPorts": 'ge-0/0/[0-23]' } } self._dao = InMemoryDao.getInstance() self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao)
def testProcessTopologyNoInventory(self): l3ClosMediation = L3ClosMediation(self.conf) podDict = { "hostOrVmCountPerLeaf": 100, "leafDeviceType": "QFX5100-24Q", "spineAS": 100, "spineDeviceType": "QFX5100", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200 } l3ClosMediation.dao.createObjects([Pod('pod1', **podDict)]) with self.assertRaises(ValueError): l3ClosMediation.processTopology("pod1")
def testCreateSpines(self): from jnpr.openclos.l3Clos import util flexmock( util, getPortNamesForDeviceFamily={'ports': ['et-0/0/0', 'et-0/0/1']}) self.conf['deviceFamily'] = {} l3ClosMediation = L3ClosMediation(self.conf) dao = l3ClosMediation.dao pod = self.createPodWithoutInventory(l3ClosMediation) spineString = u'[{ "name" : "spine-01", "mac_address" : "aa:bb:cc:dd:ee:f1", "mgmt_ip" : "172.32.32.201/24", "user" : "root", "password" : "Embe1mpls" }, { "name" : "spine-02", "mac_address" : "aa:bb:cc:dd:ee:f2", "mgmt_ip" : "172.32.32.202/24", "user" : "root", "password" : "Embe1mpls" }]' l3ClosMediation.createSpineIFDs(pod, json.loads(spineString)) self.assertEqual(2, len(dao.getAll(Device))) self.assertEqual(0, len(dao.getAll(InterfaceLogical))) self.assertEqual(4, len(dao.getAll(InterfaceDefinition))) self.assertEqual( 2, len(dao.getObjectsByName(InterfaceDefinition, 'et-0/0/0'))) self.assertEqual( 2, len(dao.getObjectsByName(InterfaceDefinition, 'et-0/0/1')))
def testAllocateIrb(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPodSpineLeaf(l3ClosMediation) session = l3ClosMediation.dao.Session() l3ClosMediation.allocateIrb(pod, '172.16.0.0', pod.devices) self.assertEqual( 4, len(l3ClosMediation.dao.getObjectsByName(InterfaceLogical, 'irb.1'))) ifl = session.query(InterfaceLogical).join(Device).filter( InterfaceLogical.name == 'irb.1').filter( Device.name == 'leaf-01').filter( Device.pod_id == pod.id).one() self.assertEqual('172.16.0.1/24', ifl.ipaddress) ifl = session.query(InterfaceLogical).join(Device).filter( InterfaceLogical.name == 'irb.1').filter( Device.name == 'spine-02').filter( Device.pod_id == pod.id).one() self.assertEqual('172.16.3.1/24', ifl.ipaddress) self.assertEqual('172.16.0.0/22', pod.allocatedIrbBlock)
def testAllocateLoopback(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPodSpineLeaf(l3ClosMediation) session = l3ClosMediation.dao.Session() l3ClosMediation.allocateLoopback(pod, "10.0.0.0", pod.devices) self.assertEqual( 4, len(l3ClosMediation.dao.getObjectsByName(InterfaceLogical, 'lo0.0'))) ifl = session.query(InterfaceLogical).join(Device).filter( InterfaceLogical.name == 'lo0.0').filter( Device.name == 'leaf-01').filter( Device.pod_id == pod.id).one() self.assertEqual('10.0.0.1/32', ifl.ipaddress) ifl = session.query(InterfaceLogical).join(Device).filter( InterfaceLogical.name == 'lo0.0').filter( Device.name == 'spine-02').filter( Device.pod_id == pod.id).one() self.assertEqual('10.0.0.4/32', ifl.ipaddress) self.assertEqual('10.0.0.0/29', pod.allocatedLoopbackBlock)
def testProcessFabricReCreateFabric(self): l3ClosMediation = L3ClosMediation(self.conf) pod = self.createPod(l3ClosMediation) podDict = { "hostOrVmCountPerLeaf": 100, "leafDeviceType": "QFX5100-48S", "spineAS": 100, "spineDeviceType": "QFX5100-24Q", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200 } l3ClosMediation = flexmock(l3ClosMediation) l3ClosMediation.should_receive('processTopology').once() newPod = l3ClosMediation.processFabric(pod.name, podDict, True) self.assertNotEqual(pod.id, newPod.id)
def testGetOpenClosTrapGroupSettingsWithStagedZtp(self): self._conf['deploymentMode'] = {'ztpStaged': True} self._conf['snmpTrap'] = { 'openclos_trap_group': { 'port': 20162, 'target': '1.2.3.4' } } self.l3ClosMediation = L3ClosMediation(self._conf, InMemoryDao) with self._dao.getReadSession() as session: self.assertEqual( 1, len(self.l3ClosMediation._getOpenclosTrapGroupSettings( session))) self.assertEqual( 1, len( self.l3ClosMediation._getOpenclosTrapGroupSettings(session) [0]['targetIp'])) self.assertEqual( '1.2.3.4', self.l3ClosMediation._getOpenclosTrapGroupSettings(session)[0] ['targetIp'][0]) self.createTrapGroupsInDb(self._dao) with self._dao.getReadSession() as session: self.assertEqual( 1, len(self.l3ClosMediation._getOpenclosTrapGroupSettings( session))) self.assertEqual( 20162, self.l3ClosMediation._getOpenclosTrapGroupSettings(session)[0] ['port']) self.assertEqual( 2, len( self.l3ClosMediation._getOpenclosTrapGroupSettings(session) [0]['targetIp']))
def testProcessTopologyMultiplePods(self): l3ClosMediation = L3ClosMediation(self.conf) podDict = { "hostOrVmCountPerLeaf": 100, "leafDeviceType": "QFX5100-24Q", "spineAS": 100, "spineDeviceType": "QFX5100", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200 } pod1 = Pod('pod1', **podDict) podDict = { "hostOrVmCountPerLeaf": 100, "leafDeviceType": "QFX5100-48S", "spineAS": 100, "spineDeviceType": "QFX5100", "leafCount": 6, "interConnectPrefix": "192.168.0.0", "spineCount": 4, "vlanPrefix": "172.16.0.0", "topologyType": "threeStage", "loopbackPrefix": "10.0.0.0", "leafAS": 200 } pod2 = Pod('pod1', **podDict) l3ClosMediation.dao.createObjects([pod1, pod2]) with self.assertRaises(ValueError) as ve: l3ClosMediation.processTopology("pod1") error = ve.exception.message self.assertEqual(1, error.count('MultipleResultsFound'))
def testLoadClosDefinition(self): l3ClosMediation = L3ClosMediation(self.conf) pods = l3ClosMediation.loadClosDefinition() self.assertEqual(2, len(pods))
def testCreatePod(self): l3ClosMediation = L3ClosMediation(self.conf) session = l3ClosMediation.dao.Session() pod = self.createPod(l3ClosMediation) self.assertEqual(1, session.query(Pod).count())
def testLoadNonExistingClosDefinition(self): l3ClosMediation = L3ClosMediation(self.conf) dao = l3ClosMediation.dao l3ClosMediation.loadClosDefinition('non-existing.yaml') self.assertEqual(0, len(dao.getAll(Pod)))