def test_check_to_reclaim_local_vlan(self): net1_port1_info = self._form_port_info_dict( 'fake_vcenter', 'fake_cluster', 'net1') ovsvapp_db.get_local_vlan(net1_port1_info) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port1_info) self.assertEqual(1, lvid)
def test_check_to_reclaim_local_vlan(self): net1_port1_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') ovsvapp_db.get_local_vlan(net1_port1_info) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port1_info) self.assertEqual(1, lvid)
def test_get_local_vlan_second_network_first_port(self): net1_port1_info = self._form_port_info_dict("fake_vcenter", "fake_cluster", "net1") ovsvapp_db.get_local_vlan(net1_port1_info) net2_port1_info = self._form_port_info_dict("fake_vcenter", "fake_cluster", "net2") lvid = ovsvapp_db.get_local_vlan(net2_port1_info) self.assertEqual(2, lvid)
def test_get_local_vlan_second_network_first_port(self): net1_port1_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') ovsvapp_db.get_local_vlan(net1_port1_info) net2_port1_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net2') lvid = ovsvapp_db.get_local_vlan(net2_port1_info) self.assertEqual(2, lvid)
def test_get_stale_local_vlans_for_network_no_stale_networks(self): net1_port_info = self._form_port_info_dict("fake_vcenter", "fake_cluster", "net1") # Allocate network. ovsvapp_db.get_local_vlan(net1_port_info) # Setup for release. lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(1, lvid) ovsvapp_db.release_local_vlan(net1_port_info) ret_val = ovsvapp_db.get_stale_local_vlans_for_network("net1") self.assertIsNone(ret_val)
def test_get_local_vlan_first_network_second_port(self): net1_port_info = self._form_port_info_dict( 'fake_vcenter', 'fake_cluster', 'net1') ovsvapp_db.get_local_vlan(net1_port_info) net2_port1_info = self._form_port_info_dict( 'fake_vcenter', 'fake_cluster', 'net2') ovsvapp_db.get_local_vlan(net2_port1_info) lvid = ovsvapp_db.get_local_vlan(net1_port_info) self.assertEqual(1, lvid)
def test_release_local_vlan(self): net1_port_info = self._form_port_info_dict("fake_vcenter", "fake_cluster", "net1") # Allocate network. ovsvapp_db.get_local_vlan(net1_port_info) # Setup for release. lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(1, lvid) with mock.patch("networking_vsphere.db.ovsvapp_db." "LOG.error") as error_log: ovsvapp_db.release_local_vlan(net1_port_info) self.assertFalse(error_log.called)
def test_get_stale_local_vlans_for_network_no_stale_networks(self): net1_port_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') # Allocate network. ovsvapp_db.get_local_vlan(net1_port_info) # Setup for release. lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(1, lvid) ovsvapp_db.release_local_vlan(net1_port_info) ret_val = ovsvapp_db.get_stale_local_vlans_for_network('net1') self.assertIsNone(ret_val)
def test_get_stale_local_vlans_for_network(self): net1_port1_info = self._form_port_info_dict("fake_vcenter", "fake_cluster1", "net1") ovsvapp_db.get_local_vlan(net1_port1_info) net1_port2_info = self._form_port_info_dict("fake_vcenter", "fake_cluster2", "net1") ovsvapp_db.get_local_vlan(net1_port2_info) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port1_info) self.assertEqual(1, lvid) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port2_info) self.assertEqual(1, lvid) ret_val = ovsvapp_db.get_stale_local_vlans_for_network("net1") self.assertEqual([("fake_vcenter", "fake_cluster1", 1), ("fake_vcenter", "fake_cluster2", 1)], ret_val)
def test_release_local_vlan(self): net1_port_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') # Allocate network. ovsvapp_db.get_local_vlan(net1_port_info) # Setup for release. lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(1, lvid) with mock.patch('networking_vsphere.db.ovsvapp_db.' 'LOG.error') as error_log: ovsvapp_db.release_local_vlan(net1_port_info) self.assertFalse(error_log.called)
def test_get_stale_local_vlans_for_network(self): net1_port1_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster1', 'net1') ovsvapp_db.get_local_vlan(net1_port1_info) net1_port2_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster2', 'net1') ovsvapp_db.get_local_vlan(net1_port2_info) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port1_info) self.assertEqual(1, lvid) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port2_info) self.assertEqual(1, lvid) ret_val = ovsvapp_db.get_stale_local_vlans_for_network('net1') self.assertEqual([('fake_vcenter', 'fake_cluster1', 1), ('fake_vcenter', 'fake_cluster2', 1)], ret_val)
def test_get_local_vlan_initialize_error(self): net1_port_info = self._form_port_info_dict( 'fake_vcenter', 'fake_cluster', 'net1') with mock.patch('networking_vsphere.db.ovsvapp_db.' '_initialize_lvids_for_cluster', return_value=False): lvid = ovsvapp_db.get_local_vlan(net1_port_info) self.assertIsNone(lvid)
def test_get_local_vlan_initialize_error(self): net1_port_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') with mock.patch( 'networking_vsphere.db.ovsvapp_db.' '_initialize_lvids_for_cluster', return_value=False): lvid = ovsvapp_db.get_local_vlan(net1_port_info) self.assertIsNone(lvid)
def test_check_to_reclaim_local_vlan_multiple_ports(self): net1_port_info = self._form_port_info_dict("fake_vcenter", "fake_cluster", "net1") ovsvapp_db.get_local_vlan(net1_port_info) ovsvapp_db.get_local_vlan(net1_port_info) ovsvapp_db.get_local_vlan(net1_port_info) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(-1, lvid) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(-1, lvid) lvid = ovsvapp_db.check_to_reclaim_local_vlan(net1_port_info) self.assertEqual(1, lvid)
def get_ports_for_device(self, rpc_context, **kwargs): """RPC for getting port info. This method provides information about the network and port for a given device_id. """ agent_id = kwargs.get('agent_id') host = kwargs.get('host') device = kwargs.get('device') device_id = device['id'] vcenter_id = device['vcenter'] cluster_id = device['cluster_id'] LOG.info(_("Device %(device_id)s details requested by agent " "%(agent_id)s running on host %(host)s."), {'device_id': device_id, 'agent_id': agent_id, 'host': host}) if not device_id: return False try_count = 3 try: while try_count > 0: ports = self.plugin.get_ports(rpc_context, filters={'device_id': [device_id]}) device_ports = [] sg_port_ids = set() for port in ports: network = self.plugin.get_network(rpc_context, port['network_id']) port.update( {'network_type': network['provider:network_type'], 'segmentation_id': network['provider:segmentation_id'], 'physical_network': network['provider:physical_network']}) if port['network_type'] == 'vxlan': port_info = {'port_id': port['id'], 'vcenter_id': vcenter_id, 'cluster_id': cluster_id, 'network_id': port['network_id']} lvid = ovsvapp_db.get_local_vlan(port_info) if lvid: port['lvid'] = lvid else: # Local VLANs are exhausted ! No point processing # further. LOG.error(_("No VLAN available in the cluster " "%(cluster)s for assignment to device " "%(device)s in vCenter %(vcenter)s."), {'device': device_id, 'cluster': cluster_id, 'vcenter': vcenter_id}) return False else: port['lvid'] = port['segmentation_id'] # Bind the port here. If binding succeeds, then # add this port to process for security groups, otheriwse # ignore it. updated_port = self.update_port_binding(rpc_context, agent_id=agent_id, port_id=port['id'], host=host) if not updated_port: LOG.error(_("Port binding failed for " "port %s."), port['id]']) # process the next port for the device continue if 'security_groups' in port: sg_port_ids.add(port['id']) new_status = (common_const.PORT_STATUS_BUILD if port['admin_state_up'] else common_const.PORT_STATUS_DOWN) if port['status'] != new_status: self.plugin.update_port_status(rpc_context, port['id'], new_status, host) device_ports.append(port) if not device_ports: try_count -= 1 LOG.warn(_("Port details could not be retrieved for " "device %s ..retrying."), device_id) time.sleep(3) else: LOG.debug("Device details returned by server: " "%s.", device_ports) # Get the SG rules for the security enabled ports. sg_payload = {} if sg_port_ids: ports = self._get_devices_info( rpc_context, sg_port_ids) sg_rules = self.plugin.security_group_rules_for_ports( rpc_context, ports) sg_payload[device_id] = sg_rules self.notifier.device_create(rpc_context, device, device_ports, sg_payload, cluster_id) return True except Exception: LOG.exception(_("Failed to retrieve port details for " "device: %s."), device_id) LOG.error(_("Failed to retrieve ports for device: %s."), device_id) return False
def get_ports_details_list(self, rpc_context, **kwargs): """Agent requests device details.""" agent_id = kwargs.get('agent_id') port_ids = kwargs.get('port_ids') vcenter_id = kwargs['vcenter_id'] cluster_id = kwargs['cluster_id'] LOG.debug("Port details requested by agent " "%(agent_id)s for ports %(ports)s.", {'ports': port_ids, 'agent_id': agent_id}) out_ports = [] for port_id in port_ids: port_db = self._get_port_db(rpc_context.session, port_id, agent_id) if not port_db: continue port = self.plugin._make_port_dict(port_db) network = self.plugin.get_network(rpc_context, port['network_id']) levels = db.get_binding_levels(rpc_context.session, port_id, port_db.port_binding.host) port_context = driver_context.PortContext(self.plugin, rpc_context, port, network, port_db.port_binding, levels) segment = port_context.top_bound_segment # Reference: ML2 Driver API changes for hierarchical port binding. bound_port = port_context.current if not segment: LOG.warning(_("Port %(port_id)s requested by agent " "%(agent_id)s on network %(network_id)s not " "bound, vif_type: %(vif_type)s."), {'port_id': port['id'], 'agent_id': agent_id, 'network_id': port['network_id'], 'vif_type': port[portbindings.VIF_TYPE]}) continue bound_port['lvid'] = None if segment[api.NETWORK_TYPE] == 'vxlan': port_info = {'port_id': bound_port['id'], 'vcenter_id': vcenter_id, 'cluster_id': cluster_id, 'network_id': bound_port['network_id']} lvid = ovsvapp_db.get_local_vlan(port_info, False) if lvid: bound_port['lvid'] = lvid else: # Local VLANs are exhausted !! No point processing # further. LOG.error(_("Local VLAN not available in the cluster" " %(cluster)s for port" " %(port_id)s in vcenter %(vcenter)s."), {'port_id': bound_port['id'], 'cluster': cluster_id, 'vcenter': vcenter_id}) continue # Skip sending back this port as there is no lvid. else: bound_port['lvid'] = segment[api.SEGMENTATION_ID] entry = {'network_id': bound_port['network_id'], 'port_id': bound_port['id'], 'lvid': bound_port['lvid'], 'mac_address': bound_port['mac_address'], 'admin_state_up': bound_port['admin_state_up'], 'network_type': segment[api.NETWORK_TYPE], 'segmentation_id': segment[api.SEGMENTATION_ID], 'physical_network': segment[api.PHYSICAL_NETWORK], 'fixed_ips': bound_port['fixed_ips'], 'device_id': bound_port['device_id'], 'device_owner': bound_port['device_owner']} LOG.debug("Adding port detail: %s.", entry) out_ports.append(entry) return out_ports
def get_ports_details_list(self, rpc_context, **kwargs): """Agent requests device details.""" agent_id = kwargs.get('agent_id') port_ids = kwargs.get('port_ids') vcenter_id = kwargs['vcenter_id'] cluster_id = kwargs['cluster_id'] LOG.debug( "Port details requested by agent " "%(agent_id)s for ports %(ports)s.", { 'ports': port_ids, 'agent_id': agent_id }) out_ports = [] for port_id in port_ids: port_db = self._get_port_db(rpc_context.session, port_id, agent_id) if not port_db: continue port = self.plugin._make_port_dict(port_db) network = self.plugin.get_network(rpc_context, port['network_id']) levels = db.get_binding_levels(rpc_context, port_id, port_db.port_binding.host) port_context = driver_context.PortContext(self.plugin, rpc_context, port, network, port_db.port_binding, levels) segment = port_context.top_bound_segment # Reference: ML2 Driver API changes for hierarchical port binding. bound_port = port_context.current if not segment: LOG.warning( _LW("Port %(port_id)s requested by agent " "%(agent_id)s on network %(network_id)s not " "bound, vif_type: %(vif_type)s."), { 'port_id': port['id'], 'agent_id': agent_id, 'network_id': port['network_id'], 'vif_type': port[portbindings.VIF_TYPE] }) continue bound_port['lvid'] = None port_info = { 'port_id': bound_port['id'], 'vcenter_id': vcenter_id, 'cluster_id': cluster_id, 'network_id': bound_port['network_id'] } lvid = ovsvapp_db.get_local_vlan(port_info, False) if lvid: bound_port['lvid'] = lvid else: # Local VLANs are exhausted !! No point processing # further. LOG.error( _LE("Local VLAN not available in the cluster" " %(cluster)s for port" " %(port_id)s in vcenter %(vcenter)s."), { 'port_id': bound_port['id'], 'cluster': cluster_id, 'vcenter': vcenter_id }) # Skip sending back this port as there is no lvid. continue entry = { 'network_id': bound_port['network_id'], 'port_id': bound_port['id'], 'lvid': bound_port['lvid'], 'mac_address': bound_port['mac_address'], 'admin_state_up': bound_port['admin_state_up'], 'network_type': segment[api.NETWORK_TYPE], 'segmentation_id': segment[api.SEGMENTATION_ID], 'physical_network': segment[api.PHYSICAL_NETWORK], 'fixed_ips': bound_port['fixed_ips'], 'device_id': bound_port['device_id'], 'security_groups': bound_port['security_groups'], 'device_owner': bound_port['device_owner'] } LOG.debug("Adding port detail: %s.", entry) out_ports.append(entry) return out_ports
def get_ports_for_device(self, rpc_context, **kwargs): """RPC for getting port info. This method provides information about the network and port for a given device_id. """ agent_id = kwargs.get('agent_id') host = kwargs.get('host') device = kwargs.get('device') device_id = device['id'] vcenter_id = device['vcenter'] cluster_id = device['cluster_id'] LOG.info( _LI("Device %(device_id)s details requested by agent " "%(agent_id)s running on host %(host)s."), { 'device_id': device_id, 'agent_id': agent_id, 'host': host }) if not device_id: return False try_count = 3 try: while try_count > 0: ports = self.plugin.get_ports( rpc_context, filters={'device_id': [device_id]}) device_ports = [] sg_port_ids = set() for port in ports: network = self.plugin.get_network(rpc_context, port['network_id']) port.update({ 'network_type': network['provider:network_type'], 'segmentation_id': network['provider:segmentation_id'], 'physical_network': network['provider:physical_network'] }) port_info = { 'port_id': port['id'], 'vcenter_id': vcenter_id, 'cluster_id': cluster_id, 'network_id': port['network_id'] } lvid = None if port['status'] != common_const.PORT_STATUS_ACTIVE: lvid = ovsvapp_db.get_local_vlan(port_info) else: lvid = ovsvapp_db.get_local_vlan(port_info, False) if lvid: port['lvid'] = lvid else: # Local VLANs are exhausted ! No point processing # further. LOG.error( _LE("No VLAN available in the cluster " "%(cluster)s for assignment to" " device %(device)s in " "vCenter %(vcenter)s."), { 'device': device_id, 'cluster': cluster_id, 'vcenter': vcenter_id }) return False # Bind the port here. If binding succeeds, then # add this port to process for security groups, otheriwse # ignore it. updated_port = self.update_port_binding(rpc_context, agent_id=agent_id, port_id=port['id'], host=host) if not updated_port: LOG.error(_LE("Port binding failed for " "port %s."), port['id]']) # process the next port for the device continue if 'security_groups' in port: sg_port_ids.add(port['id']) new_status = (common_const.PORT_STATUS_BUILD if port['admin_state_up'] else common_const.PORT_STATUS_DOWN) if port['status'] != new_status: self.plugin.update_port_status(rpc_context, port['id'], new_status, host) device_ports.append(port) if not device_ports: try_count -= 1 LOG.warning( _LW("Port details could not be retrieved for " "device %s ..retrying."), device_id) time.sleep(3) else: LOG.debug("Device details returned by server: " "%s.", device_ports) # Get the SG rules for the security enabled ports. sg_payload = {} if sg_port_ids: ports = self._get_devices_info(rpc_context, sg_port_ids) sg_rules = ( self.sg_rpc.security_group_info_for_esx_ports( rpc_context, ports)) sg_payload[device_id] = sg_rules self.notifier.device_create(rpc_context, device, device_ports, sg_payload, cluster_id) return True except Exception: LOG.exception( _LE("Failed to retrieve port details for " "device: %s."), device_id) LOG.error(_LE("Failed to retrieve ports for device: %s."), device_id) return False
def test_get_local_vlan_write_and_read(self): net1_port1_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') ovsvapp_db.get_local_vlan(net1_port1_info) lvid = ovsvapp_db.get_local_vlan(net1_port1_info, False) self.assertEqual(1, lvid)
def test_get_local_vlan_read_before_write(self): net1_port1_info = self._form_port_info_dict('fake_vcenter', 'fake_cluster', 'net1') lvid = ovsvapp_db.get_local_vlan(net1_port1_info, False) self.assertIsNone(lvid)
def test_get_local_vlan_read_before_write(self): net1_port1_info = self._form_port_info_dict( 'fake_vcenter', 'fake_cluster', 'net1') lvid = ovsvapp_db.get_local_vlan(net1_port1_info, False) self.assertIsNone(lvid)
def test_get_local_vlan_write_and_read(self): net1_port1_info = self._form_port_info_dict( 'fake_vcenter', 'fake_cluster', 'net1') ovsvapp_db.get_local_vlan(net1_port1_info) lvid = ovsvapp_db.get_local_vlan(net1_port1_info, False) self.assertEqual(1, lvid)