def test_inspect_vnic_rates(self): # construct test data test_vm_mobj = mock.MagicMock() test_vm_mobj.value = "vm-21" vnic1 = "vnic-1" vnic2 = "vnic-2" counter_name_to_id_map = { vsphere_inspector.VC_NETWORK_RX_COUNTER: 1, vsphere_inspector.VC_NETWORK_TX_COUNTER: 2 } counter_id_to_stats_map = { 1: { vnic1: 1, vnic2: 3 }, 2: { vnic1: 2, vnic2: 4 }, } def get_counter_id_side_effect(counter_full_name): return counter_name_to_id_map[counter_full_name] def query_stat_side_effect(vm_mobj, counter_id, duration): # assert inputs self.assertEqual(test_vm_mobj.value, vm_mobj.value) self.assertIn(counter_id, counter_id_to_stats_map) return counter_id_to_stats_map[counter_id] self._inspector._get_vm_mobj_not_power_off_or_raise = mock.MagicMock() self._inspector._get_vm_mobj_not_power_off_or_raise.return_value = ( test_vm_mobj) # configure vsphere operations mock with the test data ops_mock = self._inspector._ops ops_mock.get_perf_counter_id.side_effect = get_counter_id_side_effect ops_mock.query_vm_device_stats.side_effect = query_stat_side_effect result = self._inspector.inspect_vnic_rates(mock.MagicMock()) # validate result expected_stats = { vnic1: virt_inspector.InterfaceRateStats(1024, 2048), vnic2: virt_inspector.InterfaceRateStats(3072, 4096) } for vnic, rates_info in result: self.assertEqual(expected_stats[vnic.name], rates_info)
def inspect_vnic_rates(self, instance, duration): vm_mobj = self._get_vm_mobj_not_power_off_or_raise(instance) vnic_stats = {} vnic_ids = set() for net_counter in (VC_NETWORK_RX_COUNTER, VC_NETWORK_TX_COUNTER): net_counter_id = self._ops.get_perf_counter_id(net_counter) vnic_id_to_stats_map = self._ops.query_vm_device_stats( vm_mobj, net_counter_id, duration) # The sample for this map is: {4000: 0.0, vmnic5: 0.0, vmnic4: 0.0, # vmnic3: 0.0, vmnic2: 0.0, vmnic1: 0.0, vmnic0: 0.0} # "4000" is the virtual nic which we need. # And these "vmnic*" are phynical nics in the host, so we remove it vnic_id_to_stats_map = {k: v for (k, v) in vnic_id_to_stats_map.items() if not k.startswith('vmnic')} vnic_stats[net_counter] = vnic_id_to_stats_map vnic_ids.update(six.iterkeys(vnic_id_to_stats_map)) # Stats provided from vSphere are in KB/s, converting it to B/s. for vnic_id in sorted(vnic_ids): rx_bytes_rate = (vnic_stats[VC_NETWORK_RX_COUNTER] .get(vnic_id, 0) * units.Ki) tx_bytes_rate = (vnic_stats[VC_NETWORK_TX_COUNTER] .get(vnic_id, 0) * units.Ki) yield virt_inspector.InterfaceRateStats( name=vnic_id, mac=None, fref=None, parameters=None, rx_bytes_rate=rx_bytes_rate, tx_bytes_rate=tx_bytes_rate)
def inspect_vnic_rates(self, instance, duration=None): vm_moid = self._ops.get_vm_moid(instance.id) if not vm_moid: raise virt_inspector.InstanceNotFoundException( _('VM %s not found in VMware Vsphere') % instance.id) vnic_stats = {} vnic_ids = set() for net_counter in (VC_NETWORK_RX_COUNTER, VC_NETWORK_TX_COUNTER): net_counter_id = self._ops.get_perf_counter_id(net_counter) vnic_id_to_stats_map = self._ops.query_vm_device_stats( vm_moid, net_counter_id, duration) vnic_stats[net_counter] = vnic_id_to_stats_map vnic_ids.update(vnic_id_to_stats_map.iterkeys()) # Stats provided from vSphere are in KB/s, converting it to B/s. for vnic_id in vnic_ids: rx_bytes_rate = ( vnic_stats[VC_NETWORK_RX_COUNTER].get(vnic_id, 0) * units.Ki) tx_bytes_rate = ( vnic_stats[VC_NETWORK_TX_COUNTER].get(vnic_id, 0) * units.Ki) stats = virt_inspector.InterfaceRateStats(rx_bytes_rate, tx_bytes_rate) interface = virt_inspector.Interface(name=vnic_id, mac=None, fref=None, parameters=None) yield (interface, stats)
def setUp(self): super(TestNetRatesPollster, self).setUp() self.vnic0 = virt_inspector.InterfaceRateStats( name='vnet0', fref='fa163e71ec6e', mac='fa:16:3e:71:ec:6d', parameters=dict(ip='10.0.0.2', projmask='255.255.255.0', projnet='proj1', dhcp_server='10.0.0.1'), rx_bytes_rate=1, tx_bytes_rate=2) self.vnic1 = virt_inspector.InterfaceRateStats( name='vnet1', fref='fa163e71ec6f', mac='fa:16:3e:71:ec:6e', parameters=dict(ip='192.168.0.3', projmask='255.255.255.0', projnet='proj2', dhcp_server='10.0.0.2'), rx_bytes_rate=3, tx_bytes_rate=4) self.vnic2 = virt_inspector.InterfaceRateStats( name='vnet2', fref=None, mac='fa:18:4e:72:fc:7e', parameters=dict(ip='192.168.0.4', projmask='255.255.255.0', projnet='proj3', dhcp_server='10.0.0.3'), rx_bytes_rate=5, tx_bytes_rate=6) vnics = [ self.vnic0, self.vnic1, self.vnic2, ] self.inspector.inspect_vnic_rates = mock.Mock(return_value=vnics)
def inspect_vnic_rates(self, instance, duration=None): instance_name = util.instance_name(instance) vm_ref = self._lookup_by_name(instance_name) vif_refs = self._call_xenapi("VM.get_VIFs", vm_ref) if vif_refs: for vif_ref in vif_refs: vif_rec = self._call_xenapi("VIF.get_record", vif_ref) vif_metrics_ref = self._call_xenapi("VIF.get_metrics", vif_ref) vif_metrics_rec = self._call_xenapi("VIF_metrics.get_record", vif_metrics_ref) interface = virt_inspector.Interface(name=vif_rec['uuid'], mac=vif_rec['MAC'], fref=None, parameters=None) rx_rate = float(vif_metrics_rec['io_read_kbs']) * units.Ki tx_rate = float(vif_metrics_rec['io_write_kbs']) * units.Ki stats = virt_inspector.InterfaceRateStats(rx_rate, tx_rate) yield (interface, stats)
def inspect_vnic_rates(self, instance, duration): instance_name = util.instance_name(instance) vm_ref = self._lookup_by_name(instance_name) vif_refs = self.session.VM.get_VIFs(vm_ref) for vif_ref in vif_refs: vif_rec = self.session.VIF.get_record(vif_ref) rx_rate = float( self.session.VM.query_data_source( vm_ref, "vif_%s_rx" % vif_rec['device'])) tx_rate = float( self.session.VM.query_data_source( vm_ref, "vif_%s_tx" % vif_rec['device'])) yield virt_inspector.InterfaceRateStats(name=vif_rec['uuid'], mac=vif_rec['MAC'], fref=None, parameters=None, rx_bytes_rate=rx_rate, tx_bytes_rate=tx_rate)
def inspect_vnic_rates(self, instance, duration=None): instance_name = util.instance_name(instance) vm_ref = self._lookup_by_name(instance_name) vif_refs = self._call_xenapi("VM.get_VIFs", vm_ref) if vif_refs: for vif_ref in vif_refs: vif_rec = self._call_xenapi("VIF.get_record", vif_ref) rx_rate = float( self._call_xenapi("VM.query_data_source", vm_ref, "vif_%s_rx" % vif_rec['device'])) tx_rate = float( self._call_xenapi("VM.query_data_source", vm_ref, "vif_%s_tx" % vif_rec['device'])) interface = virt_inspector.Interface(name=vif_rec['uuid'], mac=vif_rec['MAC'], fref=None, parameters=None) stats = virt_inspector.InterfaceRateStats(rx_rate, tx_rate) yield (interface, stats)
def inspect_vnic_rates(self, instance, duration): """Inspect the vNIC rate statistics for an instance. :param instance: the target instance :param duration: the last 'n' seconds, over which the value should be inspected The PowerVM implementation does not make use of the duration field. :return: for each vNIC, the rate of bytes & packets received and transmitted """ # Get the current and previous sample. Delta is performed between # these two. uuid = self._puuid(instance) cur_date, cur_metric = self.vm_metrics.get_latest_metric(uuid) prev_date, prev_metric = self.vm_metrics.get_previous_metric(uuid) # If the current is none, then the instance can not be found in the # sample and an error should be raised. if cur_metric is None: raise virt_inspector.InstanceNotFoundException( _('VM %s not found in PowerVM Metrics Sample.') % instance.name) # If there isn't network information, this is because the Virtual # I/O Metrics were turned off. Have to pass through this method. if (cur_metric.network is None or prev_metric is None or prev_metric.network is None): return # Get the network interfaces. A 'cna' is a Client VM's Network Adapter client_cnas = self._get_cnas(uuid) def find_prev_net(metric_cna): """Finds the metric vNIC from the previous sample's vNICs.""" # If no previous, return None if prev_metric is None or prev_metric.network is None: return None for prev_cna in prev_metric.network.cnas: if prev_cna.physical_location == metric_cna.physical_location: return prev_cna # Couldn't find a previous. Maybe the interface was recently # added to the instance? Return None return None # Need to determine the time delta between the samples. This is # usually 30 seconds from the API, but the metrics will be specific. date_delta_num = float((cur_date - prev_date).seconds) for metric_cna in cur_metric.network.cnas: # Get the mac, but if it isn't found, then move to the next. Might # have been removed since the last sample. mac = self.mac_for_metric_cna(metric_cna, client_cnas) if mac is None: continue # Note that here, the previous may be none. That simply indicates # that the adapter was dynamically added to the VM before the # previous collection. Not the migration scenario above. # In this case, we can default the base to 0. prev = find_prev_net(metric_cna) rx_bytes_diff = (metric_cna.received_bytes - (0 if prev is None else prev.received_bytes)) tx_bytes_diff = (metric_cna.sent_bytes - (0 if prev is None else prev.sent_bytes)) # Stats are the difference in the bytes, divided by the difference # in time between the two samples. rx_rate = float(rx_bytes_diff) / float(date_delta_num) tx_rate = float(tx_bytes_diff) / float(date_delta_num) # The name will be the location code. MAC is identified from # above. Others appear libvirt specific. yield virt_inspector.InterfaceRateStats( name=metric_cna.physical_location, mac=mac, fref=None, parameters=None, rx_bytes_rate=rx_rate, tx_bytes_rate=tx_rate)