def test_create_and_delete_ports(self): tenant_id = 'ten-1' network_id = 'net1-id' segmentation_id = 1001 vms = ['vm1', 'vm2', 'vm3'] network_context = self._get_network_context(tenant_id, network_id, segmentation_id) self.drv.create_network_precommit(network_context) for vm_id in vms: port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context) self.drv.create_port_precommit(port_context) vm_list = db.get_vms(tenant_id) provisioned_vms = len(vm_list) expected_vms = len(vms) self.assertEqual( expected_vms, provisioned_vms, 'There should be %d ' 'hosts, not %d' % (expected_vms, provisioned_vms)) # Now test the delete ports for vm_id in vms: port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context) self.drv.delete_port_precommit(port_context) vm_list = db.get_vms(tenant_id) provisioned_vms = len(vm_list) expected_vms = 0 self.assertEqual( expected_vms, provisioned_vms, 'There should be %d ' 'VMs, not %d' % (expected_vms, provisioned_vms))
def test_create_and_delete_ports(self): tenant_id = "ten-1" network_id = "net1-id" segmentation_id = 1001 vms = ["vm1", "vm2", "vm3"] network_context = self._get_network_context(tenant_id, network_id, segmentation_id) self.drv.create_network_precommit(network_context) for vm_id in vms: port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context) self.drv.create_port_precommit(port_context) vm_list = db.get_vms(tenant_id) provisioned_vms = len(vm_list) expected_vms = len(vms) self.assertEqual( expected_vms, provisioned_vms, "There should be %d " "hosts, not %d" % (expected_vms, provisioned_vms) ) # Now test the delete ports for vm_id in vms: port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context) self.drv.delete_port_precommit(port_context) vm_list = db.get_vms(tenant_id) provisioned_vms = len(vm_list) expected_vms = 0 self.assertEqual( expected_vms, provisioned_vms, "There should be %d " "VMs, not %d" % (expected_vms, provisioned_vms) )
def test_create_and_delete_ports(self): tenant_id = 'ten-1' network_id = 'net1-id' segmentation_id = 1001 vms = ['vm1', 'vm2', 'vm3'] network_context = self._get_network_context(tenant_id, network_id, segmentation_id) self.drv.create_network_precommit(network_context) for vm_id in vms: port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context) self.drv.create_port_precommit(port_context) vm_list = db.get_vms(tenant_id) provisioned_vms = len(vm_list) expected_vms = len(vms) self.assertEqual(expected_vms, provisioned_vms, 'There should be %d ' 'hosts, not %d' % (expected_vms, provisioned_vms)) # Now test the delete ports for vm_id in vms: port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context) self.drv.delete_port_precommit(port_context) vm_list = db.get_vms(tenant_id) provisioned_vms = len(vm_list) expected_vms = 0 self.assertEqual(expected_vms, provisioned_vms, 'There should be %d ' 'VMs, not %d' % (expected_vms, provisioned_vms))
def test_num_vm_is_valid(self): tenant_id = "test" network_id = "123" port_id = 456 host_id = "ubuntu1" vm_to_remember = ["vm1", "vm2", "vm3"] vm_to_forget = ["vm2", "vm1"] for vm in vm_to_remember: db.remember_vm(vm, host_id, port_id, network_id, tenant_id) for vm in vm_to_forget: db.forget_vm(vm, host_id, port_id, network_id, tenant_id) num_vms = len(db.get_vms(tenant_id)) expected = len(vm_to_remember) - len(vm_to_forget) self.assertEqual(expected, num_vms, "There should be %d records, " "got %d records" % (expected, num_vms)) # clean up afterwards db.forget_vm("vm3", host_id, port_id, network_id, tenant_id)
def test_num_vm_is_valid(self): tenant_id = 'test' network_id = '123' port_id = 456 host_id = 'ubuntu1' vm_to_remember = ['vm1', 'vm2', 'vm3'] vm_to_forget = ['vm2', 'vm1'] for vm in vm_to_remember: db.remember_vm(vm, host_id, port_id, network_id, tenant_id) for vm in vm_to_forget: db.forget_vm(vm, host_id, port_id, network_id, tenant_id) num_vms = len(db.get_vms(tenant_id)) expected = len(vm_to_remember) - len(vm_to_forget) self.assertEqual(expected, num_vms, 'There should be %d records, ' 'got %d records' % (expected, num_vms)) # clean up afterwards db.forget_vm('vm3', host_id, port_id, network_id, tenant_id)
def synchronize(self): """Sends data to EOS which differs from neutron DB.""" LOG.info(_('Syncing Neutron <-> EOS')) try: eos_tenants = self._rpc.get_tenants() except arista_exc.AristaRpcError: msg = _('EOS is not available, will try sync later') LOG.warning(msg) return db_tenants = db.get_tenants() if not db_tenants and eos_tenants: # No tenants configured in Neutron. Clear all EOS state try: self._rpc.delete_this_region() msg = _('No Tenants configured in Neutron DB. But %d ' 'tenants disovered in EOS during synchronization.' 'Enitre EOS region is cleared') % len(eos_tenants) except arista_exc.AristaRpcError: msg = _('EOS is not available, failed to delete this region') LOG.warning(msg) return if len(eos_tenants) > len(db_tenants): # EOS has extra tenants configured which should not be there. for tenant in eos_tenants: if tenant not in db_tenants: try: self._rpc.delete_tenant(tenant) except arista_exc.AristaRpcError: msg = _('EOS is not available,' 'failed to delete tenant %s') % tenant LOG.warning(msg) return # EOS and Neutron has matching set of tenants. Now check # to ensure that networks and VMs match on both sides for # each tenant. for tenant in db_tenants: db_nets = db.get_networks(tenant) db_vms = db.get_vms(tenant) eos_nets = self._get_eos_networks(eos_tenants, tenant) eos_vms = self._get_eos_vms(eos_tenants, tenant) # Check for the case if everything is already in sync. if eos_nets == db_nets: # Net list is same in both Neutron and EOS. # check the vM list if eos_vms == db_vms: # Nothing to do. Everything is in sync for this tenant break # Neutron DB and EOS reruires synchronization. # First delete anything which should not be EOS # delete VMs from EOS if it is not present in neutron DB for vm_id in eos_vms: if vm_id not in db_vms: try: self._rpc.delete_vm(tenant, vm_id) except arista_exc.AristaRpcError: msg = _('EOS is not available,' 'failed to delete vm %s') % vm_id LOG.warning(msg) return # delete network from EOS if it is not present in neutron DB for net_id in eos_nets: if net_id not in db_nets: try: self._rpc.delete_network(tenant, net_id) except arista_exc.AristaRpcError: msg = _('EOS is not available,' 'failed to delete network %s') % net_id LOG.warning(msg) return # update networks in EOS if it is present in neutron DB for net_id in db_nets: if net_id not in eos_nets: vlan_id = db_nets[net_id]['segmentationTypeId'] net_name = self._ndb.get_network_name(tenant, net_id) try: self._rpc.create_network(tenant, net_id, net_name, vlan_id) except arista_exc.AristaRpcError: msg = _('EOS is not available, failed to create' 'network id %s') % net_id LOG.warning(msg) return # Update VMs in EOS if it is present in neutron DB for vm_id in db_vms: if vm_id not in eos_vms: vm = db_vms[vm_id] ports = self._ndb.get_all_ports_for_vm(tenant, vm_id) for port in ports: port_id = port['id'] network_id = port['network_id'] port_name = port['name'] try: self._rpc.plug_host_into_network(vm['vmId'], vm['host'], port_id, network_id, tenant, port_name) except arista_exc.AristaRpcError: msg = _('EOS is not available, failed to create' 'vm id %s') % vm['vmId'] LOG.warning(msg)
def synchronize(self): """Sends data to EOS which differs from neutron DB.""" LOG.info(_('Syncing Neutron <-> EOS')) try: # Get the time at which entities in the region were updated. # If the times match, then ML2 is in sync with EOS. Otherwise # perform a complete sync. if not self._force_sync and self._rpc.region_in_sync(): LOG.info(_('OpenStack and EOS are in sync!')) return except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return try: #Always 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.get_tenants() if not db_tenants and eos_tenants: # No tenants configured in Neutron. Clear all EOS state try: self._rpc.delete_this_region() msg = _('No Tenants configured in Neutron DB. But %d ' 'tenants disovered in EOS during synchronization.' 'Enitre EOS region is cleared') % len(eos_tenants) LOG.info(msg) # Re-register with EOS so that the timestamp is updated. self._rpc.register_with_eos() # Region has been completely cleaned. So there is nothing to # syncronize self._force_sync = False except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return # 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 for tenant in db_tenants: db_nets = db.get_networks(tenant) db_vms = db.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 = 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'], } for net_id in nets_to_update] self._rpc.create_network_bulk(tenant, networks) if vms_to_update: # 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 ] 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(_('Syncing Neutron <-> EOS')) try: #Always 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: msg = _('EOS is not available, will try sync later') LOG.warning(msg) return db_tenants = db.get_tenants() if not db_tenants and eos_tenants: # No tenants configured in Neutron. Clear all EOS state try: self._rpc.delete_this_region() msg = _('No Tenants configured in Neutron DB. But %d ' 'tenants disovered in EOS during synchronization.' 'Enitre EOS region is cleared') % len(eos_tenants) except arista_exc.AristaRpcError: msg = _('EOS is not available, failed to delete this region') LOG.warning(msg) return # EOS and Neutron has matching set of tenants. Now check # to ensure that networks and VMs match on both sides for # each tenant. for tenant in eos_tenants.keys(): if tenant not in db_tenants: #send delete tenant to EOS try: self._rpc.delete_tenant(tenant) del eos_tenants[tenant] except arista_exc.AristaRpcError: msg = _('EOS is not available, ' 'failed to delete tenant %s') % tenant LOG.warning(msg) for tenant in db_tenants: db_nets = db.get_networks(tenant) db_vms = db.get_vms(tenant) eos_nets = self._get_eos_networks(eos_tenants, tenant) eos_vms = self._get_eos_vms(eos_tenants, tenant) # Check for the case if everything is already in sync. if eos_nets == db_nets: # Net list is same in both Neutron and EOS. # check the vM list if eos_vms == db_vms: # Nothing to do. Everything is in sync for this tenant continue # Neutron DB and EOS reruires synchronization. # First delete anything which should not be EOS # delete VMs from EOS if it is not present in neutron DB for vm_id in eos_vms: if vm_id not in db_vms: try: self._rpc.delete_vm(tenant, vm_id) except arista_exc.AristaRpcError: msg = _('EOS is not available,' 'failed to delete vm %s') % vm_id LOG.warning(msg) # delete network from EOS if it is not present in neutron DB for net_id in eos_nets: if net_id not in db_nets: try: self._rpc.delete_network(tenant, net_id) except arista_exc.AristaRpcError: msg = _('EOS is not available,' 'failed to delete network %s') % net_id LOG.warning(msg) # update networks in EOS if it is present in neutron DB for net_id in db_nets: if net_id not in eos_nets: vlan_id = db_nets[net_id]['segmentationTypeId'] net_name = self._ndb.get_network_name(tenant, net_id) try: self._rpc.create_network(tenant, net_id, net_name, vlan_id) except arista_exc.AristaRpcError: msg = _('EOS is not available, failed to create' 'network id %s') % net_id LOG.warning(msg) # Update VMs in EOS if it is present in neutron DB for vm_id in db_vms: if vm_id not in eos_vms: vm = db_vms[vm_id] ports = self._ndb.get_all_ports_for_vm(tenant, vm_id) for port in ports: port_id = port['id'] net_id = port['network_id'] port_name = port['name'] device_owner = port['device_owner'] vm_id = vm['vmId'] host_id = vm['host'] try: self._rpc.plug_port_into_network( vm_id, host_id, port_id, net_id, tenant, port_name, device_owner) except arista_exc.AristaRpcError: msg = _('EOS is not available, failed to create ' 'vm id %s') % vm['vmId'] LOG.warning(msg)
def synchronize(self): """Sends data to EOS which differs from neutron DB.""" LOG.info(_('Syncing Neutron <-> EOS')) try: # Get the time at which entities in the region were updated. # If the times match, then ML2 is in sync with EOS. Otherwise # perform a complete sync. if not self._force_sync and self._rpc.region_in_sync(): LOG.info(_('OpenStack and EOS are in sync!')) return except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return try: #Always 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.get_tenants() if not db_tenants and eos_tenants: # No tenants configured in Neutron. Clear all EOS state try: self._rpc.delete_this_region() msg = _('No Tenants configured in Neutron DB. But %d ' 'tenants disovered in EOS during synchronization.' 'Enitre EOS region is cleared') % len(eos_tenants) LOG.info(msg) # Re-register with EOS so that the timestamp is updated. self._rpc.register_with_eos() # Region has been completely cleaned. So there is nothing to # syncronize self._force_sync = False except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True return # 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 for tenant in db_tenants: db_nets = db.get_networks(tenant) db_vms = db.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 = 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'], } for net_id in nets_to_update ] self._rpc.create_network_bulk(tenant, networks) if vms_to_update: # 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 ] self._rpc.create_vm_port_bulk(tenant, vm_ports, db_vms) except arista_exc.AristaRpcError: LOG.warning(EOS_UNREACHABLE_MSG) self._force_sync = True