def test_get_counters(self): vnic0 = virt_inspector.Interface( 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')) stats0 = virt_inspector.InterfaceStats(rx_bytes=1L, rx_packets=2L, tx_bytes=3L, tx_packets=4L) vnic1 = virt_inspector.Interface( 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')) stats1 = virt_inspector.InterfaceStats(rx_bytes=5L, rx_packets=6L, tx_bytes=7L, tx_packets=8L) vnics = [(vnic0, stats0), (vnic1, stats1)] self.inspector.inspect_vnics(self.instance.name).AndReturn(vnics) self.mox.ReplayAll() mgr = manager.AgentManager() pollster = pollsters.NetPollster() counters = list(pollster.get_counters(mgr, self.instance)) assert counters self.assertEqual(set([c.name for c in counters]), set(pollster.get_counter_names())) def _verify_vnic_metering(name, ip, expected_volume): match = [c for c in counters if c.name == name and c.resource_metadata['parameters']['ip'] == ip] self.assertEquals(len(match), 1, 'missing counter %s' % name) self.assertEquals(match[0].volume, expected_volume) self.assertEquals(match[0].type, 'cumulative') _verify_vnic_metering('network.incoming.bytes', '10.0.0.2', 1L) _verify_vnic_metering('network.incoming.bytes', '192.168.0.3', 5L) _verify_vnic_metering('network.outgoing.bytes', '10.0.0.2', 3L) _verify_vnic_metering('network.outgoing.bytes', '192.168.0.3', 7L) _verify_vnic_metering('network.incoming.packets', '10.0.0.2', 2L) _verify_vnic_metering('network.incoming.packets', '192.168.0.3', 6L) _verify_vnic_metering('network.outgoing.packets', '10.0.0.2', 4L) _verify_vnic_metering('network.outgoing.packets', '192.168.0.3', 8L)
def inspect_vnics(self, instance): instance_name = util.instance_name(instance) vm_ref = self._lookup_by_name(instance_name) dom_id = self._call_xenapi("VM.get_domid", vm_ref) vif_refs = self._call_xenapi("VM.get_VIFs", vm_ref) bw_all = self._call_plugin_serialized('bandwidth', 'fetch_all_bandwidth') for vif_ref in vif_refs or []: vif_rec = self._call_xenapi("VIF.get_record", vif_ref) interface = virt_inspector.Interface(name=vif_rec['uuid'], mac=vif_rec['MAC'], fref=None, parameters=None) bw_vif = bw_all[dom_id][vif_rec['device']] # TODO(jianghuaw): Currently the plugin can only support # rx_bytes and tx_bytes, so temporarily set others as -1. stats = virt_inspector.InterfaceStats(rx_bytes=bw_vif['bw_in'], rx_packets=-1, rx_drop=-1, rx_errors=-1, tx_bytes=bw_vif['bw_out'], tx_packets=-1, tx_drop=-1, tx_errors=-1) yield (interface, stats)
def inspect_vnics(self, instance_name): domain = self._lookup_by_name(instance_name) state = domain.info()[0] if state == libvirt.VIR_DOMAIN_SHUTOFF: LOG.warn(_('Failed to inspect vnics of %(instance_name)s, ' 'domain is in state of SHUTOFF'), {'instance_name': instance_name}) return tree = etree.fromstring(domain.XMLDesc(0)) for iface in tree.findall('devices/interface'): target = iface.find('target') if target is not None: name = target.get('dev') else: continue mac = iface.find('mac') if mac is not None: mac_address = mac.get('address') else: continue fref = iface.find('filterref') if fref is not None: fref = fref.get('filter') params = dict((p.get('name').lower(), p.get('value')) for p in iface.findall('filterref/parameter')) interface = virt_inspector.Interface(name=name, mac=mac_address, fref=fref, parameters=params) dom_stats = domain.interfaceStats(name) stats = virt_inspector.InterfaceStats(rx_bytes=dom_stats[0], rx_packets=dom_stats[1], tx_bytes=dom_stats[4], tx_packets=dom_stats[5]) yield (interface, stats)
def inspect_vnics(self, instance): domain = self._get_domain_not_shut_off_or_raise(instance) tree = etree.fromstring(domain.XMLDesc(0)) for iface in tree.findall('devices/interface'): target = iface.find('target') if target is not None: name = target.get('dev') else: continue mac = iface.find('mac') if mac is not None: mac_address = mac.get('address') else: continue fref = iface.find('filterref') if fref is not None: fref = fref.get('filter') params = dict((p.get('name').lower(), p.get('value')) for p in iface.findall('filterref/parameter')) interface = virt_inspector.Interface(name=name, mac=mac_address, fref=fref, parameters=params) dom_stats = domain.interfaceStats(name) stats = virt_inspector.InterfaceStats(rx_bytes=dom_stats[0], rx_packets=dom_stats[1], tx_bytes=dom_stats[4], tx_packets=dom_stats[5]) yield (interface, stats)
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 _check_get_samples_cache(self, factory): vnic0 = virt_inspector.Interface(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')) stats0 = virt_inspector.InterfaceStats(rx_bytes=1, rx_packets=2, rx_drop=20, rx_errors=21, tx_bytes=3, tx_packets=4, tx_drop=22, tx_errors=23) vnics = [(vnic0, stats0)] mgr = manager.AgentManager(0, self.CONF) pollster = factory(self.CONF) cache = { pollster.CACHE_KEY_VNIC: { self.instance.id: vnics, }, } samples = list(pollster.get_samples(mgr, cache, [self.instance])) self.assertEqual(1, len(samples))
def setUp(self): super(TestNetPollster, self).setUp() self.vnic0 = virt_inspector.Interface(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')) stats0 = virt_inspector.InterfaceStats(rx_bytes=1L, rx_packets=2L, tx_bytes=3L, tx_packets=4L) self.vnic1 = virt_inspector.Interface(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')) stats1 = virt_inspector.InterfaceStats(rx_bytes=5L, rx_packets=6L, tx_bytes=7L, tx_packets=8L) self.vnic2 = virt_inspector.Interface(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')) stats2 = virt_inspector.InterfaceStats(rx_bytes=9L, rx_packets=10L, tx_bytes=11L, tx_packets=12L) vnics = [ (self.vnic0, stats0), (self.vnic1, stats1), (self.vnic2, stats2), ] self.inspector.inspect_vnics(self.instance.name).AndReturn(vnics) self.mox.ReplayAll()
def setUp(self): super(TestNetRatesPollster, self).setUp() self.vnic0 = virt_inspector.Interface(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')) stats0 = virt_inspector.InterfaceRateStats(rx_bytes_rate=1L, tx_bytes_rate=2L) self.vnic1 = virt_inspector.Interface(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')) stats1 = virt_inspector.InterfaceRateStats(rx_bytes_rate=3L, tx_bytes_rate=4L) self.vnic2 = virt_inspector.Interface(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')) stats2 = virt_inspector.InterfaceRateStats(rx_bytes_rate=5L, tx_bytes_rate=6L) vnics = [ (self.vnic0, stats0), (self.vnic1, stats1), (self.vnic2, stats2), ] self.inspector.inspect_vnic_rates = mock.Mock(return_value=vnics)
def inspect_vnics(self, instance): """Inspect the vNIC statistics for an instance. :param instance: the target instance :return: for each vNIC, the number 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) # If the cur_metric 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: return # Get the network interfaces. A 'cna' is a Client VM's Network Adapter client_cnas = self._get_cnas(uuid) 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 # The name will be the location code. MAC is identified from # above. Others appear libvirt specific. interface = virt_inspector.Interface( name=metric_cna.physical_location, mac=mac, fref=None, parameters=None) stats = virt_inspector.InterfaceStats( rx_bytes=metric_cna.received_bytes, rx_packets=metric_cna.received_packets, tx_bytes=metric_cna.sent_bytes, tx_packets=metric_cna.sent_packets) # Yield the stats up to the invoker yield (interface, stats)
def inspect_vnics(self, instance_name): for vnic_metrics in self._utils.get_vnic_metrics(instance_name): interface = virt_inspector.Interface( name=vnic_metrics["element_name"], mac=vnic_metrics["address"], fref=None, parameters=None) stats = virt_inspector.InterfaceStats( rx_bytes=vnic_metrics['rx_bytes'], rx_packets=0, tx_bytes=vnic_metrics['tx_bytes'], tx_packets=0) yield (interface, stats)
def inspect_vnics(self, instance): inst_stat = self._get_inst_stat('vnics', instance) for nic in inst_stat['nics']: interface = virt_inspector.Interface(name=nic['nic_vdev'], mac=None, fref=None, parameters=None) stats = virt_inspector.InterfaceStats( rx_bytes=nic['nic_rx'], rx_packets=nic['nic_fr_rx'], tx_bytes=nic['nic_tx'], tx_packets=nic['nic_fr_tx'], rx_drop=nic['nic_fr_rx_dsc'], tx_drop=nic['nic_fr_tx_dsc'], rx_errors=nic['nic_fr_rx_err'], tx_errors=nic['nic_fr_tx_err']) yield (interface, stats)
def inspect_vnics(self, instance_name): domain = self._lookup_by_name(instance_name) tree = etree.fromstring(domain.XMLDesc(0)) for iface in tree.findall('devices/interface'): name = iface.find('target').get('dev') mac = iface.find('mac').get('address') fref = iface.find('filterref').get('filter') params = dict((p.get('name').lower(), p.get('value')) for p in iface.findall('filterref/parameter')) interface = virt_inspector.Interface(name=name, mac=mac, fref=fref, parameters=params) rx_bytes, rx_packets, _, _, \ tx_bytes, tx_packets, _, _ = domain.interfaceStats(name) stats = virt_inspector.InterfaceStats(rx_bytes=rx_bytes, rx_packets=rx_packets, tx_bytes=tx_bytes, tx_packets=tx_packets) yield (interface, stats)
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=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=None): 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 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(TestNetPollster, self).setUp() self.vnic0 = virt_inspector.Interface(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')) stats0 = virt_inspector.InterfaceStats(rx_bytes=1L, rx_packets=2L, tx_bytes=3L, tx_packets=4L) self.vnic1 = virt_inspector.Interface(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')) stats1 = virt_inspector.InterfaceStats(rx_bytes=5L, rx_packets=6L, tx_bytes=7L, tx_packets=8L) self.vnic2 = virt_inspector.Interface(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')) stats2 = virt_inspector.InterfaceStats(rx_bytes=9L, rx_packets=10L, tx_bytes=11L, tx_packets=12L) vnics = [ (self.vnic0, stats0), (self.vnic1, stats1), (self.vnic2, stats2), ] self.inspector.inspect_vnics = mock.Mock(return_value=vnics) self.INSTANCE_PROPERTIES = { 'name': 'display name', 'OS-EXT-SRV-ATTR:instance_name': 'instance-000001', 'OS-EXT-AZ:availability_zone': 'foo-zone', 'reservation_id': 'reservation id', 'id': 'instance id', 'user_id': 'user id', 'tenant_id': 'tenant id', 'architecture': 'x86_64', 'kernel_id': 'kernel id', 'os_type': 'linux', 'ramdisk_id': 'ramdisk id', 'status': 'active', 'ephemeral_gb': 0, 'root_gb': 20, 'disk_gb': 20, 'image': { 'id': 1, 'links': [{ "rel": "bookmark", 'href': 2 }] }, 'hostId': '1234-5678', 'flavor': { 'id': 1, 'disk': 20, 'ram': 512, 'vcpus': 2, 'ephemeral': 0 }, 'metadata': { 'metering.autoscale.group': 'X' * 512, 'metering.ephemeral_gb': 42 } } self.faux_instance = FauxInstance(**self.INSTANCE_PROPERTIES)
def inspect_vnics(self, instance): domain = self._get_domain_not_shut_off_or_raise(instance) tree = etree.fromstring(domain.XMLDesc(0)) for iface in tree.findall('devices/interface'): if iface.get('type') != PORT_DIRECT_TYPE: #Not SRIOV generator = super(MlnxLibvirtInspector, self).inspect_vnics(instance_name) if hasattr(generator, "__iter__"): for gen in generator: yield gen return mac = iface.find('mac') if mac is not None: mac_address = mac.get('address') else: continue args = ["ip", "link", "show"] try: (output, rc) = utils.execute(*args) except: LOG.warning('Unable to run command: %s' % output) continue lines = output.split(os.linesep) name = vf_num = None for line in reversed(lines): if mac_address in line: try: vf_num = int( self.regex_get_number.search(line).group()) except: pass elif vf_num is not None: if self.regex_get_number.match(line) is not None: name = self.regex_get_string.split(line)[1].strip() break if vf_num is None or name is None: LOG.warning( 'Unable to reach counters: unknown VF number and interface name' ) continue #filtertref (fref) is not supported in SRIOV interface = virt_inspector.Interface(name=name, mac=mac_address, fref=None, parameters=None) self._init_vf_counters(name, vf_num) stats = virt_inspector.InterfaceStats( rx_bytes=self.counters_dic["rx_bytes"], rx_packets=self.counters_dic["rx_packets"], tx_bytes=self.counters_dic["tx_bytes"], tx_packets=self.counters_dic["tx_packets"]) yield (interface, stats)
def inspect_vnic_rates(self, instance, duration=None): """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 # The name will be the location code. MAC is identified from # above. Others appear libvirt specific. interface = virt_inspector.Interface( name=metric_cna.physical_location, mac=mac, fref=None, parameters=None) # 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) stats = virt_inspector.InterfaceRateStats(rx_rate, tx_rate) # Yield the results back to the invoker. yield (interface, stats)