def test_vmotion_vlan_available(controller, database, vcenter_api_client, vm_registered_update, vn_model_1, vlan_id_pool): """ When the VLAN ID is available on a host, we should not change it""" # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) # Some vlan ids should be already reserved reserve_vlan_ids(vlan_id_pool, [0, 1]) # When we ask vCenter for the VLAN ID it turns out that the VLAN ID has already been overridden vcenter_api_client.get_vlan_id.return_value = 5 # A new update containing VmRegisteredEvent arrives and is being handled by the controller controller.handle_update(vm_registered_update) # Check if VLAN ID has been changed vmi_model = next(model for model in database.get_all_vmi_models() if model.display_name == 'vmi-DPG1-VM1') vcenter_api_client.set_vlan_id.assert_not_called() # Check inner VMI model state vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') assert_vmi_model_state( vmi_model, mac_address='mac-address', ip_address='192.168.100.5', vlan_id=5, display_name='vmi-DPG1-VM1', vn_model=vn_model_1, vm_model=vm_model )
def test_vm_created_vlan_id_collision(controller, database, vcenter_api_client, vm_created_update, vn_model_1, vmi_model_2, vlan_id_pool): # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) vmi_model_2.vcenter_port.vlan_id = 1 database.save(vmi_model_2) # Some vlan ids should be already reserved reserve_vlan_ids(vlan_id_pool, [0, 1]) # When we ask vCenter for the VLAN ID it turns out that the VLAN ID has already been overridden vcenter_api_client.get_vlan_id.return_value = 1 # A new update containing VmCreatedEvent arrives and is being handled by the controller controller.handle_update(vm_created_update) # Check if VLAN ID has been set vcenter_api_client.set_vlan_id.assert_called_once() # Check inner VMI model state vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') vmi_model = next(model for model in database.get_all_vmi_models() if model.display_name == 'vmi-DPG1-VM1') assert_vmi_model_state( vmi_model, mac_address='mac-address', ip_address='192.168.100.5', vlan_id=2, display_name='vmi-DPG1-VM1', vn_model=vn_model_1, vm_model=vm_model )
def test_vm_created_vlan_id(controller, database, vcenter_api_client, vm_created_update, vn_model_1, vlan_id_pool): """ What happens when the created interface is already using an overriden VLAN ID? We should keep it (if it's available on the host), not removing old/adding new VLAN ID, since it breaks the connectivity for a moment. """ # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) # Some vlan ids should be already reserved reserve_vlan_ids(vlan_id_pool, [0, 1]) # When we ask vCenter for the VLAN ID it turns out that the VLAN ID has already been overridden vcenter_api_client.get_vlan_id.return_value = 5 # A new update containing VmCreatedEvent arrives and is being handled by the controller controller.handle_update(vm_created_update) # Check if VLAN ID has not been changed vcenter_api_client.set_vlan_id.assert_not_called() # Check inner VMI model state vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') vmi_model = database.get_all_vmi_models()[0] assert_vmi_model_state( vmi_model, mac_address='mac-address', ip_address='192.168.100.5', vlan_id=5, display_name='vmi-DPG1-VM1', vn_model=vn_model_1, vm_model=vm_model )
def test_assign_new_vlan_id(vlan_id_service, database, vcenter_api_client, vlan_id_pool, vmi_model): database.vlans_to_update.append(vmi_model) reserve_vlan_ids(vlan_id_pool, [0, 1]) vcenter_api_client.get_vlan_id.return_value = None vlan_id_service.update_vlan_ids() assert vmi_model.vcenter_port.vlan_id == 2 assert not database.vlans_to_update
def test_full_remove_vm(controller, database, vcenter_api_client, vnc_api_client, vrouter_api_client, vm_created_update, vm_removed_update, vn_model_1, vlan_id_pool): # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) # In this scenario vCenter should return no relocation vcenter_api_client.is_vm_removed.return_value = True # Some vlan ids should be already reserved vcenter_api_client.get_vlan_id.return_value = None reserve_vlan_ids(vlan_id_pool, [0, 1, 2, 3]) # A new update containing VmCreatedEvent arrives and is being handled by the controller controller.handle_update(vm_created_update) # After VmCreatedEvent has been handled # proper VM model should exists vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') assert vm_model is not None # And associated VMI model vmi_models = vm_model.vmi_models assert len(vmi_models) == 1 vmi_model = vmi_models[0] assert vmi_model is not None # And proper VLAN ID should be acquired assert not vlan_id_pool.is_available(4) # The VM is not present on any other ESXi vcenter_api_client.can_remove_vm.return_value = True # Then VmRemovedEvent is being handled controller.handle_update(vm_removed_update) # Check that VM Model has been removed from Database: assert database.get_vm_model_by_uuid(vm_model.uuid) is None # Check that VM has been removed from VNC vnc_api_client.delete_vm.assert_called_once_with(vm_model.uuid) # Check that VMI Model which was associated with removed VM has been removed # from Database vmi_models = database.get_vmi_models_by_vm_uuid(vm_model.uuid) assert vmi_models == [] # from VNC vnc_api_client.delete_vmi.assert_called_with(vmi_model.uuid) # Check that VMI's vRouter Port has been deleted: vrouter_api_client.delete_port.assert_called_once_with(vmi_model.uuid) vrouter_api_client.add_port.assert_called_once() # Check that VLAN ID has been released vcenter_api_client.restore_vlan_id.assert_called_once_with(vmi_model.vcenter_port) assert vlan_id_pool.is_available(4)
def test_restore_vlan_id(vlan_id_service, database, vcenter_api_client, vlan_id_pool, vmi_model): reserve_vlan_ids(vlan_id_pool, [20]) database.vlans_to_restore.append(vmi_model) vmi_model.vcenter_port.vlan_id = 20 vlan_id_service.update_vlan_ids() vcenter_api_client.restore_vlan_id.assert_called_once_with( vmi_model.vcenter_port) assert vlan_id_pool.is_available(20) assert not database.vlans_to_restore
def test_current_not_available(vlan_id_service, database, vcenter_api_client, vlan_id_pool, vmi_model, vmi_model_2): database.vlans_to_update.append(vmi_model) vmi_model_2.vcenter_port.vlan_id = 20 database.save(vmi_model_2) vcenter_api_client.get_vlan_id.return_value = 20 reserve_vlan_ids(vlan_id_pool, [20]) vlan_id_service.update_vlan_ids() assert vmi_model.vcenter_port.vlan_id == 0 assert not database.vlans_to_update
def test_vm_created(controller, database, vcenter_api_client, vnc_api_client, vrouter_api_client, vlan_id_pool, vm_created_update, vnc_vn_1, vn_model_1): # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) # Some vlan ids should be already reserved vcenter_api_client.get_vlan_id.return_value = None reserve_vlan_ids(vlan_id_pool, [0, 1]) # A new update containing VmCreatedEvent arrives and is being handled by the controller controller.handle_update(vm_created_update) # Check if VM Model has been saved properly: # - in VNC: vnc_api_client.update_vm.assert_called_once() vnc_vm = vnc_api_client.update_vm.call_args[0][0] assert_vnc_vm_state(vnc_vm, uuid='vmware-vm-uuid-1', name='vmware-vm-uuid-1', owner='project-uuid') # - in Database: vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') assert_vm_model_state(vm_model, uuid='vmware-vm-uuid-1', name='VM1') # Check if VMI Model has been saved properly: # - in VNC vnc_api_client.update_vmi.assert_called_once() vnc_vmi = vnc_api_client.update_vmi.call_args[0][0] assert_vnc_vmi_state(vnc_vmi, mac_address='mac-address', vnc_vm_uuid=vnc_vm.uuid, vnc_vn_uuid=vnc_vn_1.uuid) # - in Database vmi_model = database.get_all_vmi_models()[0] # Check if VMI Model's Instance IP has been created in VNC: vnc_api_client.create_and_read_instance_ip.assert_called_once() # Check if VMI's vRouter Port has been added: vrouter_api_client.read_port.assert_called_once() vrouter_api_client.delete_port.assert_not_called() vrouter_api_client.add_port.assert_called_once_with(vmi_model) vrouter_api_client.disable_port.assert_not_called() # Check if VLAN ID has been set using VLAN Override vcenter_port = vcenter_api_client.set_vlan_id.call_args[0][0] assert vcenter_port.port_key == '10' assert vcenter_port.vlan_id == 2 # Check inner VMI model state assert_vmi_model_state(vmi_model, mac_address='mac-address', ip_address='192.168.100.5', vlan_id=2, display_name='vmi-DPG1-VM1', vn_model=vn_model_1, vm_model=vm_model)
def test_vm_removed_local_remove(controller, database, vcenter_api_client, vnc_api_client, vrouter_api_client, vm_created_update, vm_removed_update, vn_model_1, vlan_id_pool): """ Same situation as in test_full_remove_vm, but between VmCreatedEvent and VmDeletedEvent VM changed its ESXi host. It happens during vMotion. So we have to remove that VM and its associated objects from database and vRouter. But cannot remove them from VNC and vCenter """ # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) # In this scenario vCenter should return info about relocation vcenter_api_client.is_vm_removed.return_value = False # Some vlan ids should be already reserved vcenter_api_client.get_vlan_id.return_value = None reserve_vlan_ids(vlan_id_pool, [0, 1, 2, 3]) # A new update containing VmCreatedEvent arrives and is being handled by the controller controller.handle_update(vm_created_update) # After VmCreatedEvent has been handled # proper VM model should exists vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') assert vm_model is not None # And associated VMI model vmi_models = vm_model.vmi_models assert len(vmi_models) == 1 vmi_model = vmi_models[0] assert vmi_model is not None # And proper VLAN ID should be acquired assert not vlan_id_pool.is_available(4) # The VM is present on some other ESXi vcenter_api_client.can_remove_vm.return_value = False # Then VmRemovedEvent is being handled controller.handle_update(vm_removed_update) # Check that VM Model has been removed from Database: assert database.get_vm_model_by_uuid(vm_model.uuid) is None # Cannot remove VM from VNC vnc_api_client.delete_vm.assert_not_called() # Check that VMI Model which was associated with removed VM has been removed # from Database vmi_models = database.get_vmi_models_by_vm_uuid(vm_model.uuid) assert vmi_models == [] # Cannot remove VMI from VNC vnc_api_client.delete_vmi.assert_not_called() # Check that VMI's vRouter Port has been deleted: vrouter_api_client.delete_port.assert_called_once_with(vmi_model.uuid) vrouter_api_client.add_port.assert_called_once # Cannot remove VLAN ID from vCenter vcenter_api_client.restore_vlan_id.assert_not_called() # Check that VLAN ID has been restored to local pool assert vlan_id_pool.is_available(4)
def test_vm_reconfigured(controller, database, vcenter_api_client, vnc_api_client, vrouter_api_client, vm_created_update, vm_reconfigured_update, vmware_vm_1, vn_model_1, vnc_vn_2, vn_model_2, vlan_id_pool): # Virtual Networks are already created for us and after synchronization, # their models are stored in our database database.save(vn_model_1) database.save(vn_model_2) # Some vlan ids should be already reserved vcenter_api_client.get_vlan_id.return_value = None reserve_vlan_ids(vlan_id_pool, [0, 1, 2, 3]) # A new update containing VmCreatedEvent arrives and is being handled by the controller controller.handle_update(vm_created_update) # After a portgroup is changed, the port key is also changed vmware_vm_1.config.hardware.device[ 0].backing.port.portgroupKey = 'dvportgroup-2' vmware_vm_1.config.hardware.device[0].backing.port.portKey = '11' # Then VmReconfiguredEvent is being handled controller.handle_update(vm_reconfigured_update) # Check if VM Model has been saved properly in Database: vm_model = database.get_vm_model_by_uuid('vmware-vm-uuid-1') assert_vm_model_state(vm_model, has_ports={'mac-address': 'dvportgroup-2'}) # Check that VM was not updated in VNC except VM create event vnc_api_client.update_vm.assert_called_once() # Check if VMI Model has been saved properly: # - in Database vmi_models = database.get_vmi_models_by_vm_uuid('vmware-vm-uuid-1') assert len(vmi_models) == 1 vmi_model = vmi_models[0] # - in VNC assert vnc_api_client.update_vmi.call_count == 2 vnc_vmi = vnc_api_client.update_vmi.call_args[0][0] assert vnc_vmi.get_virtual_network_refs()[0]['uuid'] == vnc_vn_2.uuid # Check if VMI Model's Instance IP has been updated in VNC: assert vnc_api_client.create_and_read_instance_ip.call_count == 2 new_instance_ip = vmi_model.vnc_instance_ip assert vnc_api_client.create_and_read_instance_ip.call_args[0][ 0] == vmi_model assert vnc_vn_2.uuid in [ ref['uuid'] for ref in new_instance_ip.get_virtual_network_refs() ] # Check if VMI's vRouter Port has been updated: vrouter_api_client.delete_port.assert_called_once_with(vmi_model.uuid) assert vrouter_api_client.add_port.call_count == 2 assert vrouter_api_client.add_port.call_args[0][0] == vmi_model # Check if VLAN ID has been set using VLAN Override assert vcenter_api_client.set_vlan_id.call_count == 2 vcenter_port = vcenter_api_client.set_vlan_id.call_args[0][0] assert vcenter_port.port_key == '11' assert vcenter_port.vlan_id == 5 # Check inner VMI model state assert_vmi_model_state(vmi_model, mac_address='mac-address', ip_address='192.168.100.5', vlan_id=5, display_name='vmi-DPG2-VM1', vn_model=vn_model_2)