Merge "Adds metrics collection support in Hyper-V"
This commit is contained in:
commit
b944ed485c
@ -39,6 +39,12 @@
|
||||
# local_network_vswitch = private
|
||||
# Example: local_network_vswitch = custom_vswitch
|
||||
|
||||
# (BoolOpt) Enables metrics collections for switch ports by using Hyper-V's
|
||||
# metric APIs. Collected data can by retrieved by other apps and services,
|
||||
# e.g.: Ceilometer. Requires Hyper-V / Windows Server 2012 and above.
|
||||
#
|
||||
# enable_metrics_collection = False
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Sample Configurations.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
@ -52,6 +52,13 @@ agent_opts = [
|
||||
cfg.IntOpt('polling_interval', default=2,
|
||||
help=_("The number of seconds the agent will wait between "
|
||||
"polling for local device changes.")),
|
||||
cfg.BoolOpt('enable_metrics_collection',
|
||||
default=False,
|
||||
help=_('Enables metrics collections for switch ports by using '
|
||||
'Hyper-V\'s metric APIs. Collected data can by '
|
||||
'retrieved by other apps and services, e.g.: '
|
||||
'Ceilometer. Requires Hyper-V / Windows Server 2012 '
|
||||
'and above'))
|
||||
]
|
||||
|
||||
|
||||
@ -210,6 +217,9 @@ class HyperVNeutronAgent(object):
|
||||
else:
|
||||
LOG.error(_('Unsupported network type %s'), network_type)
|
||||
|
||||
if CONF.AGENT.enable_metrics_collection:
|
||||
self._utils.enable_port_metrics_collection(port_id)
|
||||
|
||||
def _port_unbound(self, port_id):
|
||||
(net_uuid, map) = self._get_network_vswitch_map_by_port_id(port_id)
|
||||
if net_uuid not in self._network_vswitch_map:
|
||||
|
@ -243,3 +243,7 @@ class HyperVUtils(object):
|
||||
for switch_port in switch_ports:
|
||||
if (switch_port.ElementName == port_id):
|
||||
return switch_port
|
||||
|
||||
def enable_port_metrics_collection(self, switch_port_name):
|
||||
raise NotImplementedError(_("Metrics collection is not supported on "
|
||||
"this version of Hyper-V"))
|
||||
|
@ -26,10 +26,18 @@ class HyperVUtilsV2(utils.HyperVUtils):
|
||||
_ETHERNET_SWITCH_PORT = 'Msvm_EthernetSwitchPort'
|
||||
_PORT_ALLOC_SET_DATA = 'Msvm_EthernetPortAllocationSettingData'
|
||||
_PORT_VLAN_SET_DATA = 'Msvm_EthernetSwitchPortVlanSettingData'
|
||||
_PORT_ALLOC_ACL_SET_DATA = 'Msvm_EthernetSwitchPortAclSettingData'
|
||||
_LAN_ENDPOINT = 'Msvm_LANEndpoint'
|
||||
_STATE_DISABLED = 3
|
||||
_OPERATION_MODE_ACCESS = 1
|
||||
|
||||
_ACL_DIR_IN = 1
|
||||
_ACL_DIR_OUT = 2
|
||||
_ACL_TYPE_IPV4 = 2
|
||||
_ACL_TYPE_IPV6 = 3
|
||||
_ACL_ACTION_METER = 3
|
||||
_ACL_APPLICABILITY_LOCAL = 1
|
||||
|
||||
_wmi_namespace = '//./root/virtualization/v2'
|
||||
|
||||
def __init__(self):
|
||||
@ -159,3 +167,26 @@ class HyperVUtilsV2(utils.HyperVUtils):
|
||||
def _get_first_item(self, obj):
|
||||
if obj:
|
||||
return obj[0]
|
||||
|
||||
def enable_port_metrics_collection(self, switch_port_name):
|
||||
port, found = self._get_switch_port_allocation(switch_port_name, False)
|
||||
if not found:
|
||||
return
|
||||
|
||||
# Add the ACLs only if they don't already exist
|
||||
acls = port.associators(wmi_result_class=self._PORT_ALLOC_ACL_SET_DATA)
|
||||
for acl_type in [self._ACL_TYPE_IPV4, self._ACL_TYPE_IPV6]:
|
||||
for acl_dir in [self._ACL_DIR_IN, self._ACL_DIR_OUT]:
|
||||
acls = [v for v in acls
|
||||
if v.Action == self._ACL_ACTION_METER and
|
||||
v.Applicability == self._ACL_APPLICABILITY_LOCAL and
|
||||
v.Direction == acl_dir and
|
||||
v.AclType == acl_type]
|
||||
if not acls:
|
||||
acl = self._get_default_setting_data(
|
||||
self._PORT_ALLOC_ACL_SET_DATA)
|
||||
acl.AclType = acl_type
|
||||
acl.Direction = acl_dir
|
||||
acl.Action = self._ACL_ACTION_METER
|
||||
acl.Applicability = self._ACL_APPLICABILITY_LOCAL
|
||||
self._add_virt_feature(port, acl)
|
||||
|
@ -213,3 +213,18 @@ class TestHyperVUtilsV2(base.BaseTestCase):
|
||||
True)
|
||||
|
||||
self.assertEqual(ret_val, (mock_data, False))
|
||||
|
||||
def test_enable_port_metrics_collection(self):
|
||||
mock_port = mock.MagicMock()
|
||||
self._utils._get_switch_port_allocation = mock.MagicMock(return_value=(
|
||||
mock_port, True))
|
||||
|
||||
mock_acl = mock.MagicMock()
|
||||
self._utils._get_default_setting_data = mock.MagicMock(
|
||||
return_value=mock_acl)
|
||||
self._utils._add_virt_feature = mock.MagicMock()
|
||||
|
||||
self._utils.enable_port_metrics_collection(self._FAKE_PORT_NAME)
|
||||
|
||||
self.assertEqual(4, len(self._utils._add_virt_feature.mock_calls))
|
||||
self._utils._add_virt_feature.assert_called_with(mock_port, mock_acl)
|
||||
|
Loading…
Reference in New Issue
Block a user