def test_get_network_list_returns_eos_compatible_data(self): tenant = u'test-1' segm_type = 'vlan' network_id = u'123' network2_id = u'1234' vlan_id = 123 vlan2_id = 1234 expected_eos_net_list = { network_id: { u'networkId': network_id, u'segmentationTypeId': vlan_id, u'segmentationType': segm_type }, network2_id: { u'networkId': network2_id, u'segmentationTypeId': vlan2_id, u'segmentationType': segm_type } } db_lib.remember_network(tenant, network_id, vlan_id) db_lib.remember_network(tenant, network2_id, vlan2_id) net_list = db_lib.get_networks(tenant) self.assertNotEqual(net_list != expected_eos_net_list, ('%s != %s' % (net_list, expected_eos_net_list)))
def test_cleanup_on_start(self): """Ensures that the driver cleans up the arista database on startup.""" ndb = db_lib.NeutronNets() # Create some networks in neutron db n1_context = self._get_network_context('t1', 'n1', 10) ndb.create_network(n1_context, {'network': n1_context.current}) n2_context = self._get_network_context('t2', 'n2', 20) ndb.create_network(n2_context, {'network': n2_context.current}) n3_context = self._get_network_context('', 'ha-network', 100) ndb.create_network(n3_context, {'network': n3_context.current}) # Create some networks in Arista db db_lib.remember_network('t1', 'n1', 10) db_lib.remember_network('t2', 'n2', 20) db_lib.remember_network('admin', 'ha-network', 100) db_lib.remember_network('t3', 'n3', 30) # Initialize the driver which should clean up the extra networks self.drv.initialize() adb_networks = db_lib.get_networks(tenant_id='any') # 'n3' should now be deleted from the Arista DB assert(set(('n1', 'n2', 'ha-network')) == set(adb_networks.keys()))
def _cleanup_db(self): """Clean up any uncessary entries in our DB.""" db_tenants = db_lib.get_tenants() for tenant in db_tenants: neutron_nets = self.ndb.get_all_networks_for_tenant(tenant) neutron_nets_id = [] for net in neutron_nets: neutron_nets_id.append(net['id']) db_nets = db_lib.get_networks(tenant) for net_id in db_nets.keys(): if net_id not in neutron_nets_id: db_lib.forget_network(tenant, net_id)
def _cleanup_db(self): """Clean up any uncessary entries in our DB.""" neutron_nets = self.ndb.get_all_networks() arista_db_nets = db_lib.get_networks(tenant_id='any') neutron_net_ids = set() for net in neutron_nets: neutron_net_ids.add(net['id']) # Remove networks from the Arista DB if the network does not exist in # Neutron DB for net_id in set(arista_db_nets.keys()).difference(neutron_net_ids): tenant_network = arista_db_nets[net_id] db_lib.forget_network(tenant_network['tenantId'], net_id)
def test_get_network_list_returns_eos_compatible_data(self): tenant = u'test-1' segm_type = 'vlan' network_id = u'123' network2_id = u'1234' vlan_id = 123 vlan2_id = 1234 expected_eos_net_list = {network_id: {u'networkId': network_id, u'segmentationTypeId': vlan_id, u'segmentationType': segm_type}, network2_id: {u'networkId': network2_id, u'segmentationTypeId': vlan2_id, u'segmentationType': segm_type}} db_lib.remember_network(tenant, network_id, vlan_id) db_lib.remember_network(tenant, network2_id, vlan2_id) net_list = db_lib.get_networks(tenant) self.assertNotEqual(net_list != expected_eos_net_list, ('%s != %s' % (net_list, expected_eos_net_list)))
def synchronize(self): """Sends data to EOS which differs from neutron DB.""" LOG.info(_LI('Syncing Neutron <-> EOS')) try: # Register with EOS to ensure that it has correct credentials self._rpc.register_with_eos() eos_tenants = self._rpc.get_tenants() except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return db_tenants = db_lib.get_tenants() # Delete tenants that are in EOS, but not in the database tenants_to_delete = frozenset(eos_tenants.keys()).difference( db_tenants.keys()) if tenants_to_delete: try: self._rpc.delete_tenant_bulk(tenants_to_delete) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return # None of the commands have failed till now. But if subsequent # operations fail, then force_sync is set to true self._force_sync = False # To support shared networks, split the sync loop in two parts: # In first loop, delete unwanted VM and networks and update networks # In second loop, update VMs. This is done to ensure that networks for # all tenats are updated before VMs are updated vms_to_update = {} for tenant in db_tenants: db_nets = db_lib.get_networks(tenant) db_vms = db_lib.get_vms(tenant) eos_nets = self._get_eos_networks(eos_tenants, tenant) eos_vms = self._get_eos_vms(eos_tenants, tenant) db_nets_key_set = frozenset(db_nets.keys()) db_vms_key_set = frozenset(db_vms.keys()) eos_nets_key_set = frozenset(eos_nets.keys()) eos_vms_key_set = frozenset(eos_vms.keys()) # Find the networks that are present on EOS, but not in Neutron DB nets_to_delete = eos_nets_key_set.difference(db_nets_key_set) # Find the VMs that are present on EOS, but not in Neutron DB vms_to_delete = eos_vms_key_set.difference(db_vms_key_set) # Find the Networks that are present in Neutron DB, but not on EOS nets_to_update = db_nets_key_set.difference(eos_nets_key_set) # Find the VMs that are present in Neutron DB, but not on EOS vms_to_update[tenant] = db_vms_key_set.difference(eos_vms_key_set) try: if vms_to_delete: self._rpc.delete_vm_bulk(tenant, vms_to_delete) if nets_to_delete: self._rpc.delete_network_bulk(tenant, nets_to_delete) if nets_to_update: # Create a dict of networks keyed by id. neutron_nets = dict( (network['id'], network) for network in self._ndb.get_all_networks_for_tenant( tenant)) networks = [{ 'network_id': net_id, 'segmentation_id': db_nets[net_id]['segmentationTypeId'], 'network_name': neutron_nets.get(net_id, {'name': ''})['name'], 'shared': neutron_nets.get(net_id, {'shared': False})['shared'], } for net_id in nets_to_update] self._rpc.create_network_bulk(tenant, networks) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True # Now update the VMs for tenant in vms_to_update: if not vms_to_update[tenant]: continue try: # Filter the ports to only the vms that we are interested # in. vm_ports = [ port for port in self._ndb.get_all_ports_for_tenant(tenant) if port['device_id'] in vms_to_update[tenant] ] if vm_ports: db_vms = db_lib.get_vms(tenant) self._rpc.create_vm_port_bulk(tenant, vm_ports, db_vms) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True
def synchronize(self): """Sends data to EOS which differs from neutron DB.""" LOG.info(_LI('Syncing Neutron <-> EOS')) try: # Register with EOS to ensure that it has correct credentials self._rpc.register_with_eos() eos_tenants = self._rpc.get_tenants() except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return db_tenants = db_lib.get_tenants() # Delete tenants that are in EOS, but not in the database tenants_to_delete = frozenset(eos_tenants.keys()).difference( db_tenants.keys()) if tenants_to_delete: try: self._rpc.delete_tenant_bulk(tenants_to_delete) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return # None of the commands have failed till now. But if subsequent # operations fail, then force_sync is set to true self._force_sync = False # To support shared networks, split the sync loop in two parts: # In first loop, delete unwanted VM and networks and update networks # In second loop, update VMs. This is done to ensure that networks for # all tenats are updated before VMs are updated vms_to_update = {} for tenant in db_tenants: db_nets = db_lib.get_networks(tenant) db_vms = db_lib.get_vms(tenant) eos_nets = self._get_eos_networks(eos_tenants, tenant) eos_vms = self._get_eos_vms(eos_tenants, tenant) db_nets_key_set = frozenset(db_nets.keys()) db_vms_key_set = frozenset(db_vms.keys()) eos_nets_key_set = frozenset(eos_nets.keys()) eos_vms_key_set = frozenset(eos_vms.keys()) # Find the networks that are present on EOS, but not in Neutron DB nets_to_delete = eos_nets_key_set.difference(db_nets_key_set) # Find the VMs that are present on EOS, but not in Neutron DB vms_to_delete = eos_vms_key_set.difference(db_vms_key_set) # Find the Networks that are present in Neutron DB, but not on EOS nets_to_update = db_nets_key_set.difference(eos_nets_key_set) # Find the VMs that are present in Neutron DB, but not on EOS vms_to_update[tenant] = db_vms_key_set.difference(eos_vms_key_set) try: if vms_to_delete: self._rpc.delete_vm_bulk(tenant, vms_to_delete) if nets_to_delete: self._rpc.delete_network_bulk(tenant, nets_to_delete) if nets_to_update: # Create a dict of networks keyed by id. neutron_nets = dict( (network['id'], network) for network in self._ndb.get_all_networks_for_tenant(tenant) ) networks = [{ 'network_id': net_id, 'segmentation_id': db_nets[net_id]['segmentationTypeId'], 'network_name': neutron_nets.get(net_id, {'name': ''})['name'], 'shared': neutron_nets.get(net_id, {'shared': False})['shared'], } for net_id in nets_to_update ] self._rpc.create_network_bulk(tenant, networks) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True # Now update the VMs for tenant in vms_to_update: if not vms_to_update[tenant]: continue try: # Filter the ports to only the vms that we are interested # in. vm_ports = [ port for port in self._ndb.get_all_ports_for_tenant( tenant) if port['device_id'] in vms_to_update[tenant] ] if vm_ports: db_vms = db_lib.get_vms(tenant) self._rpc.create_vm_port_bulk(tenant, vm_ports, db_vms) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True