Merge "Do not drop floating IPs/VPNs with unknown status"
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from ceilometer.i18n import _
|
||||
from ceilometer.network.services import base
|
||||
from ceilometer import sample
|
||||
|
||||
@@ -41,11 +42,15 @@ class FloatingIPPollster(base.BaseServicesPollster):
|
||||
def get_samples(self, manager, cache, resources):
|
||||
|
||||
for fip in resources or []:
|
||||
if fip['status'] is None:
|
||||
LOG.warning("Invalid status, skipping IP address %s" %
|
||||
fip['floating_ip_address'])
|
||||
continue
|
||||
LOG.debug("FLOATING IP : %s", fip)
|
||||
status = self.get_status_id(fip['status'])
|
||||
if status == -1:
|
||||
LOG.warning(
|
||||
_("Unknown status %(status)s for floating IP address "
|
||||
"%(address)s (%(id)s), setting volume to -1") % {
|
||||
"status": fip['status'],
|
||||
"address": fip['floating_ip_address'],
|
||||
"id": fip['id']})
|
||||
yield sample.Sample(
|
||||
name='ip.floating',
|
||||
type=sample.TYPE_GAUGE,
|
||||
|
||||
@@ -38,5 +38,7 @@ class BaseServicesPollster(plugin_base.PollsterBase):
|
||||
|
||||
@staticmethod
|
||||
def get_status_id(value):
|
||||
if not value:
|
||||
return -1
|
||||
status = value.lower()
|
||||
return STATUS.get(status, -1)
|
||||
|
||||
@@ -29,9 +29,7 @@ class VPNServicesDiscovery(_BaseServicesDiscovery):
|
||||
def discover(self, manager, param=None):
|
||||
"""Discover resources to monitor."""
|
||||
|
||||
vpnservices = self.neutron_cli.vpn_get_all()
|
||||
return [i for i in vpnservices
|
||||
if i.get('status', None) != 'error']
|
||||
return self.neutron_cli.vpn_get_all()
|
||||
|
||||
|
||||
class IPSecConnectionsDiscovery(_BaseServicesDiscovery):
|
||||
|
||||
@@ -41,15 +41,15 @@ class VPNServicesPollster(base.BaseServicesPollster):
|
||||
resources = resources or []
|
||||
|
||||
for vpn in resources:
|
||||
LOG.debug("VPN : %s" % vpn)
|
||||
LOG.debug("VPN : %s", vpn)
|
||||
status = self.get_status_id(vpn['status'])
|
||||
if status == -1:
|
||||
# unknown status, skip this sample
|
||||
LOG.warning(_("Unknown status %(stat)s received on vpn "
|
||||
"%(id)s, skipping sample")
|
||||
% {'stat': vpn['status'], 'id': vpn['id']})
|
||||
continue
|
||||
|
||||
LOG.warning(
|
||||
_("Unknown status %(status)s for VPN %(name)s (%(id)s), "
|
||||
"setting volume to -1") % {
|
||||
"status": vpn['status'],
|
||||
"name": vpn['name'],
|
||||
"id": vpn['id']})
|
||||
yield sample.Sample(
|
||||
name='network.services.vpn',
|
||||
type=sample.TYPE_GAUGE,
|
||||
@@ -90,7 +90,7 @@ class IPSecConnectionsPollster(base.BaseServicesPollster):
|
||||
resources = resources or []
|
||||
|
||||
for conn in resources:
|
||||
LOG.debug("IPSec Connection Info: %s" % conn)
|
||||
LOG.debug("IPSec Connection Info: %s", conn)
|
||||
|
||||
yield sample.Sample(
|
||||
name='network.services.vpn.connections',
|
||||
|
||||
@@ -43,15 +43,15 @@ class TestVPNServicesPollster(_BaseTestVPNPollster):
|
||||
def setUp(self):
|
||||
super(TestVPNServicesPollster, self).setUp()
|
||||
self.pollster = vpnaas.VPNServicesPollster(self.CONF)
|
||||
fake_vpn = self.fake_get_vpn_service()
|
||||
self.fake_vpn = self.fake_get_vpn_service()
|
||||
self.useFixture(fixtures.MockPatch('ceilometer.neutron_client.Client.'
|
||||
'vpn_get_all',
|
||||
return_value=fake_vpn))
|
||||
return_value=self.fake_vpn))
|
||||
|
||||
@staticmethod
|
||||
def fake_get_vpn_service():
|
||||
return [{'status': 'ACTIVE',
|
||||
'name': 'myvpn',
|
||||
'name': 'myvpn1',
|
||||
'description': '',
|
||||
'admin_state_up': True,
|
||||
'id': 'fdde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
@@ -59,7 +59,7 @@ class TestVPNServicesPollster(_BaseTestVPNPollster):
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'INACTIVE',
|
||||
'name': 'myvpn',
|
||||
'name': 'myvpn2',
|
||||
'description': '',
|
||||
'admin_state_up': True,
|
||||
'id': 'cdde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
@@ -67,7 +67,7 @@ class TestVPNServicesPollster(_BaseTestVPNPollster):
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'PENDING_CREATE',
|
||||
'name': 'myvpn',
|
||||
'name': 'myvpn3',
|
||||
'description': '',
|
||||
'id': 'bdde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
'admin_state_up': True,
|
||||
@@ -75,49 +75,70 @@ class TestVPNServicesPollster(_BaseTestVPNPollster):
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'error',
|
||||
'name': 'myvpn',
|
||||
'name': 'myvpn4',
|
||||
'description': '',
|
||||
'id': 'edde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
'admin_state_up': False,
|
||||
'subnet_id': 'bbe3d818-bdcb-4e4b-b47f-5650dc8a9d7a',
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'UNKNOWN',
|
||||
'name': 'myvpn5',
|
||||
'description': '',
|
||||
'id': '34e6383a-b1ab-4602-b26a-a1ae7b759212',
|
||||
'admin_state_up': False,
|
||||
'subnet_id': '8c20bbbf-1409-4bc4-b652-3aeda66746c1',
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': '0e5c9333-2ef5-4c90-9cca-5cc898515da4'},
|
||||
{'status': None,
|
||||
'name': 'myvpn6',
|
||||
'description': '',
|
||||
'id': '6e94ff61-8dea-4154-98f1-4020e4b2cecd',
|
||||
'admin_state_up': False,
|
||||
'subnet_id': '5e2a20c3-547a-43e4-90c5-26d32ea42d10',
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': '5b14df87-60c1-4fc7-8ad5-7811b2199c7f'},
|
||||
]
|
||||
|
||||
def test_vpn_get_samples(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_vpn_service()))
|
||||
self.assertEqual(4, len(samples))
|
||||
for field in self.pollster.FIELDS:
|
||||
self.assertEqual(self.fake_get_vpn_service()[0][field],
|
||||
samples[0].resource_metadata[field])
|
||||
resources=self.fake_vpn))
|
||||
self.assertEqual(len(self.fake_vpn), len(samples))
|
||||
self.assertEqual(set(vpn['id'] for vpn in self.fake_vpn),
|
||||
set(sample.resource_id for sample in samples))
|
||||
samples_dict = {sample.resource_id: sample for sample in samples}
|
||||
for vpn in self.fake_vpn:
|
||||
sample = samples_dict[vpn['id']]
|
||||
for field in self.pollster.FIELDS:
|
||||
self.assertEqual(vpn[field],
|
||||
sample.resource_metadata[field])
|
||||
|
||||
def test_vpn_volume(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_vpn_service()))
|
||||
resources=self.fake_vpn))
|
||||
self.assertEqual(1, samples[0].volume)
|
||||
self.assertEqual(0, samples[1].volume)
|
||||
self.assertEqual(2, samples[2].volume)
|
||||
self.assertEqual(7, samples[3].volume)
|
||||
self.assertEqual(-1, samples[4].volume)
|
||||
self.assertEqual(-1, samples[5].volume)
|
||||
|
||||
def test_get_vpn_meter_names(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_vpn_service()))
|
||||
resources=self.fake_vpn))
|
||||
self.assertEqual(set(['network.services.vpn']),
|
||||
set([s.name for s in samples]))
|
||||
|
||||
def test_vpn_discovery(self):
|
||||
discovered_vpns = discovery.VPNServicesDiscovery(
|
||||
self.CONF).discover(self.manager)
|
||||
self.assertEqual(3, len(discovered_vpns))
|
||||
self.assertEqual(len(self.fake_vpn), len(discovered_vpns))
|
||||
|
||||
for vpn in self.fake_get_vpn_service():
|
||||
if vpn['status'] == 'error':
|
||||
self.assertNotIn(vpn, discovered_vpns)
|
||||
else:
|
||||
self.assertIn(vpn, discovered_vpns)
|
||||
self.assertIn(vpn, discovered_vpns)
|
||||
|
||||
|
||||
class TestIPSecConnectionsPollster(_BaseTestVPNPollster):
|
||||
|
||||
@@ -39,10 +39,10 @@ class TestFloatingIPPollster(_BaseTestFloatingIPPollster):
|
||||
def setUp(self):
|
||||
super(TestFloatingIPPollster, self).setUp()
|
||||
self.pollster = floatingip.FloatingIPPollster(self.CONF)
|
||||
fake_fip = self.fake_get_fip_service()
|
||||
self.fake_fip = self.fake_get_fip_service()
|
||||
self.useFixture(fixtures.MockPatch('ceilometer.neutron_client.Client.'
|
||||
'fip_get_all',
|
||||
return_value=fake_fip))
|
||||
return_value=self.fake_fip))
|
||||
|
||||
@staticmethod
|
||||
def fake_get_fip_service():
|
||||
@@ -72,31 +72,60 @@ class TestFloatingIPPollster(_BaseTestFloatingIPPollster):
|
||||
'fixed_ip_address': '10.0.0.8',
|
||||
'floating_ip_address': '65.79.162.13',
|
||||
'port_id': '67a0d2c7-a397-444c-9d75-d2ac89b6f209',
|
||||
'id': '90ca27bf-72bc-40c8-9c13-414d564ea367'}]
|
||||
'id': '90ca27bf-72bc-40c8-9c13-414d564ea367'},
|
||||
{'router_id': 'a27ac630-939f-4e2e-bbc3-09a6b4f19a77',
|
||||
'status': 'UNKNOWN',
|
||||
'tenant_id': '54a0gggg50ee4c4396b2f8dc220a2bed57',
|
||||
'floating_network_id':
|
||||
'4d0c3f4f-79c7-40ff-9b0d-6e3a396547db',
|
||||
'fixed_ip_address': '10.0.0.9',
|
||||
'floating_ip_address': '65.79.162.14',
|
||||
'port_id': '59cc6efa-7c89-4730-b051-b15f594e6728',
|
||||
'id': 'a8a11884-7666-4f35-901e-dbb84e7111b5'},
|
||||
{'router_id': '7eb0adde-6c3b-4a77-9714-f718a17afb83',
|
||||
'status': None,
|
||||
'tenant_id': '54a0gggg50ee4c4396b2f8dc220a2bed57',
|
||||
'floating_network_id':
|
||||
'bd6290e6-b014-4cd3-91f0-7e8a1b4c26ab',
|
||||
'fixed_ip_address': '10.0.0.10',
|
||||
'floating_ip_address': '65.79.162.15',
|
||||
'port_id': 'd3b9436d-4b2b-4832-852b-34df7513c935',
|
||||
'id': '27c539ca-94ce-42fc-a639-1bf2c8690d76'}]
|
||||
|
||||
def test_fip_get_samples(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_fip_service()))
|
||||
self.assertEqual(3, len(samples))
|
||||
for field in self.pollster.FIELDS:
|
||||
self.assertEqual(self.fake_get_fip_service()[0][field],
|
||||
samples[0].resource_metadata[field])
|
||||
resources=self.fake_fip))
|
||||
self.assertEqual(len(self.fake_fip), len(samples))
|
||||
self.assertEqual(set(fip['id'] for fip in self.fake_fip),
|
||||
set(sample.resource_id for sample in samples))
|
||||
samples_dict = {sample.resource_id: sample for sample in samples}
|
||||
for fip in self.fake_fip:
|
||||
sample = samples_dict[fip['id']]
|
||||
for field in self.pollster.FIELDS:
|
||||
self.assertEqual(fip[field],
|
||||
sample.resource_metadata[field])
|
||||
|
||||
def test_fip_volume(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_fip_service()))
|
||||
resources=self.fake_fip))
|
||||
self.assertEqual(1, samples[0].volume)
|
||||
self.assertEqual(3, samples[1].volume)
|
||||
self.assertEqual(7, samples[2].volume)
|
||||
self.assertEqual(-1, samples[3].volume)
|
||||
self.assertEqual(-1, samples[4].volume)
|
||||
|
||||
def test_get_fip_meter_names(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_fip_service()))
|
||||
resources=self.fake_fip))
|
||||
self.assertEqual(set(['ip.floating']),
|
||||
set([s.name for s in samples]))
|
||||
|
||||
def test_fip_discovery(self):
|
||||
discovered_fips = discovery.FloatingIPDiscovery(
|
||||
self.CONF).discover(self.manager)
|
||||
self.assertEqual(3, len(discovered_fips))
|
||||
self.assertEqual(len(self.fake_fip), len(discovered_fips))
|
||||
for fip in self.fake_fip:
|
||||
self.assertIn(fip, discovered_fips)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The ``ip.floating`` and ``network.services.vpn`` pollsters now publish
|
||||
samples for all found floating IPs and VPNs, even if they are known
|
||||
to have an unknown state, when they would previously be dropped.
|
||||
The volume of samples for such floating IPs and VPNs will be set to
|
||||
``-1``.
|
||||
This improves visibility of floating IPs and VPNs with unknown states,
|
||||
allowing them to be monitored via samples and the Gnocchi metrics,
|
||||
making it easier to discover such resources for troubleshooting.
|
||||
It also moves some of the "business logic" for downstream rating/billing
|
||||
services such as CloudKitty out of Ceilometer itself.
|
||||
- |
|
||||
The ``network.services.vpn`` now publishes samples for VPNs with
|
||||
status ``ERROR``, when they would previously be dropped.
|
||||
The sample volume for VPNs in ``ERROR`` state is ``7``.
|
||||
Reference in New Issue
Block a user