Add support for metering VPNaaS
Change-Id: Ida9e04b13d54ab4853a4ba30d2148ac7bc8ba244 Partially-Implements: blueprint ceilometer-meter-vpnaas
This commit is contained in:
parent
6840237574
commit
94d6c9a017
@ -76,3 +76,28 @@ class LBHealthMonitorsDiscovery(_BaseServicesDiscovery):
|
||||
|
||||
probes = self.neutron_cli.health_monitor_get_all()
|
||||
return probes
|
||||
|
||||
|
||||
class VPNServicesDiscovery(_BaseServicesDiscovery):
|
||||
|
||||
def __init__(self):
|
||||
super(VPNServicesDiscovery, self).__init__()
|
||||
|
||||
def discover(self, 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']
|
||||
|
||||
|
||||
class IPSecConnectionsDiscovery(_BaseServicesDiscovery):
|
||||
|
||||
def __init__(self):
|
||||
super(IPSecConnectionsDiscovery, self).__init__()
|
||||
|
||||
def discover(self, param=None):
|
||||
"""Discover resources to monitor."""
|
||||
|
||||
conns = self.neutron_cli.ipsec_site_connections_get_all()
|
||||
return conns
|
||||
|
93
ceilometer/network/services/vpnaas.py
Normal file
93
ceilometer/network/services/vpnaas.py
Normal file
@ -0,0 +1,93 @@
|
||||
#
|
||||
# Copyright 2014 Cisco Systems,Inc.
|
||||
#
|
||||
# Author: Pradeep Kilambi <pkilambi@cisco.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ceilometer.network.services import base
|
||||
from ceilometer.openstack.common import log
|
||||
from ceilometer.openstack.common import timeutils
|
||||
from ceilometer import sample
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class VPNServicesPollster(base.BaseServicesPollster):
|
||||
"""Pollster to capture VPN status samples."""
|
||||
|
||||
FIELDS = ['admin_state_up',
|
||||
'description',
|
||||
'name',
|
||||
'status',
|
||||
'subnet_id',
|
||||
'router_id'
|
||||
]
|
||||
|
||||
def get_samples(self, manager, cache, resources=None):
|
||||
for vpn in resources:
|
||||
LOG.debug("VPN : %s" % vpn)
|
||||
status = self.get_status_id(vpn['status'])
|
||||
if status == -1:
|
||||
# unknown status, skip this sample
|
||||
LOG.warn("Unknown status %s received on vpn %s, "
|
||||
"skipping sample" % (vpn['status'], vpn['id']))
|
||||
continue
|
||||
|
||||
yield sample.Sample(
|
||||
name='network.services.vpn',
|
||||
type=sample.TYPE_GAUGE,
|
||||
unit='vpn',
|
||||
volume=status,
|
||||
user_id=None,
|
||||
project_id=vpn['tenant_id'],
|
||||
resource_id=vpn['id'],
|
||||
timestamp=timeutils.utcnow().isoformat(),
|
||||
resource_metadata=self.extract_metadata(vpn)
|
||||
)
|
||||
|
||||
|
||||
class IPSecConnectionsPollster(base.BaseServicesPollster):
|
||||
"""Pollster to capture VPN status samples."""
|
||||
|
||||
FIELDS = ['name',
|
||||
'description',
|
||||
'peer_address',
|
||||
'peer_id',
|
||||
'peer_cidrs',
|
||||
'psk',
|
||||
'initiator',
|
||||
'ikepolicy_id',
|
||||
'dpd',
|
||||
'ipsecpolicy_id',
|
||||
'vpnservice_id',
|
||||
'mtu',
|
||||
'admin_state_up',
|
||||
'tenant_id'
|
||||
]
|
||||
|
||||
def get_samples(self, manager, cache, resources=None):
|
||||
for conn in resources:
|
||||
LOG.debug("IPSec Connection Info: %s" % conn)
|
||||
|
||||
yield sample.Sample(
|
||||
name='network.services.vpn.connections',
|
||||
type=sample.TYPE_GAUGE,
|
||||
unit='vpn',
|
||||
volume=1,
|
||||
user_id=None,
|
||||
project_id=conn['tenant_id'],
|
||||
resource_id=conn['id'],
|
||||
timestamp=timeutils.utcnow().isoformat(),
|
||||
resource_metadata=self.extract_metadata(conn)
|
||||
)
|
@ -96,3 +96,13 @@ class Client(object):
|
||||
@logged
|
||||
def pool_stats(self, pool):
|
||||
return self.client.retrieve_pool_stats(pool)
|
||||
|
||||
@logged
|
||||
def vpn_get_all(self):
|
||||
resp = self.client.list_vpnservices()
|
||||
return resp.get('vpnservices')
|
||||
|
||||
@logged
|
||||
def ipsec_site_connections_get_all(self):
|
||||
resp = self.client.list_ipsec_site_connections()
|
||||
return resp.get('ipsec_site_connections')
|
||||
|
171
ceilometer/tests/network/services/test_vpnaas.py
Normal file
171
ceilometer/tests/network/services/test_vpnaas.py
Normal file
@ -0,0 +1,171 @@
|
||||
#
|
||||
# Copyright 2014 Cisco Systems,Inc.
|
||||
#
|
||||
# Author: Pradeep Kilambi <pkilambi@cisco.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from ceilometer.central import manager
|
||||
from ceilometer.network.services import discovery
|
||||
from ceilometer.network.services import vpnaas
|
||||
from ceilometer.openstack.common import context
|
||||
from ceilometer.openstack.common.fixture import mockpatch
|
||||
from ceilometer.openstack.common import test
|
||||
|
||||
|
||||
class _BaseTestVPNPollster(test.BaseTestCase):
|
||||
|
||||
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||
def setUp(self):
|
||||
super(_BaseTestVPNPollster, self).setUp()
|
||||
self.addCleanup(mock.patch.stopall)
|
||||
self.context = context.get_admin_context()
|
||||
self.manager = manager.AgentManager()
|
||||
|
||||
|
||||
class TestVPNServicesPollster(_BaseTestVPNPollster):
|
||||
|
||||
def setUp(self):
|
||||
super(TestVPNServicesPollster, self).setUp()
|
||||
self.pollster = vpnaas.VPNServicesPollster()
|
||||
fake_vpn = self.fake_get_vpn_service()
|
||||
self.useFixture(mockpatch.Patch('ceilometer.neutron_client.Client.'
|
||||
'vpn_get_all',
|
||||
return_value=fake_vpn))
|
||||
|
||||
@staticmethod
|
||||
def fake_get_vpn_service():
|
||||
return [{'status': 'ACTIVE',
|
||||
'name': 'myvpn',
|
||||
'description': '',
|
||||
'admin_state_up': True,
|
||||
'id': 'fdde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
'subnet_id': 'bbe3d818-bdcb-4e4b-b47f-5650dc8a9d7a',
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'INACTIVE',
|
||||
'name': 'myvpn',
|
||||
'description': '',
|
||||
'admin_state_up': True,
|
||||
'id': 'cdde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
'subnet_id': 'bbe3d818-bdcb-4e4b-b47f-5650dc8a9d7a',
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'PENDING_CREATE',
|
||||
'name': 'myvpn',
|
||||
'description': '',
|
||||
'id': 'bdde3d818-fdcb-fg4b-de7f-6750dc8a9d7a',
|
||||
'admin_state_up': True,
|
||||
'subnet_id': 'bbe3d818-bdcb-4e4b-b47f-5650dc8a9d7a',
|
||||
'tenant_id': 'a4eb9f4938bb418bbc4f8eb31802fefa',
|
||||
'router_id': 'ade3d818-fdcb-fg4b-de7f-6750dc8a9d7a'},
|
||||
{'status': 'error',
|
||||
'name': 'myvpn',
|
||||
'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'},
|
||||
]
|
||||
|
||||
def test_vpn_get_samples(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_vpn_service()))
|
||||
self.assertEqual(3, len(samples))
|
||||
for field in self.pollster.FIELDS:
|
||||
self.assertEqual(self.fake_get_vpn_service()[0][field],
|
||||
samples[0].resource_metadata[field])
|
||||
|
||||
def test_vpn_volume(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_vpn_service()))
|
||||
self.assertEqual(1, samples[0].volume)
|
||||
self.assertEqual(0, samples[1].volume)
|
||||
self.assertEqual(2, samples[2].volume)
|
||||
|
||||
def test_get_vpn_meter_names(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_vpn_service()))
|
||||
self.assertEqual(set(['network.services.vpn']),
|
||||
set([s.name for s in samples]))
|
||||
|
||||
def test_vpn_discovery(self):
|
||||
discovered_vpns = discovery.VPNServicesDiscovery().discover()
|
||||
self.assertEqual(3, len(discovered_vpns))
|
||||
|
||||
for vpn in self.fake_get_vpn_service():
|
||||
if vpn['status'] == 'error':
|
||||
self.assertTrue(vpn not in discovered_vpns)
|
||||
else:
|
||||
self.assertTrue(vpn in discovered_vpns)
|
||||
|
||||
|
||||
class TestIPSecConnectionsPollster(_BaseTestVPNPollster):
|
||||
|
||||
def setUp(self):
|
||||
super(TestIPSecConnectionsPollster, self).setUp()
|
||||
self.pollster = vpnaas.IPSecConnectionsPollster()
|
||||
fake_conns = self.fake_get_ipsec_connections()
|
||||
self.useFixture(mockpatch.Patch('ceilometer.neutron_client.Client.'
|
||||
'ipsec_site_connections_get_all',
|
||||
return_value=fake_conns))
|
||||
|
||||
@staticmethod
|
||||
def fake_get_ipsec_connections():
|
||||
return [{'name': 'connection1',
|
||||
'description': 'Remote-connection1',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_id': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24',
|
||||
'192.168.3.0/24'],
|
||||
'mtu': 1500,
|
||||
'psk': 'abcd',
|
||||
'initiator': 'bi-directional',
|
||||
'dpd': {
|
||||
'action': 'hold',
|
||||
'interval': 30,
|
||||
'timeout': 120},
|
||||
'ikepolicy_id': 'ade3d818-fdcb-fg4b-de7f-4550dc8a9d7a',
|
||||
'ipsecpolicy_id': 'fce3d818-fdcb-fg4b-de7f-7850dc8a9d7a',
|
||||
'vpnservice_id': 'dce3d818-fdcb-fg4b-de7f-5650dc8a9d7a',
|
||||
'admin_state_up': True,
|
||||
'tenant_id': 'abe3d818-fdcb-fg4b-de7f-6650dc8a9d7a',
|
||||
'id': 'fdfbcec-fdcb-fg4b-de7f-6650dc8a9d7a'}
|
||||
]
|
||||
|
||||
def test_conns_get_samples(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_ipsec_connections()))
|
||||
self.assertEqual(1, len(samples))
|
||||
for field in self.pollster.FIELDS:
|
||||
self.assertEqual(self.fake_get_ipsec_connections()[0][field],
|
||||
samples[0].resource_metadata[field])
|
||||
|
||||
def test_get_conns_meter_names(self):
|
||||
samples = list(self.pollster.get_samples(
|
||||
self.manager, {},
|
||||
resources=self.fake_get_ipsec_connections()))
|
||||
self.assertEqual(set(['network.services.vpn.connections']),
|
||||
set([s.name for s in samples]))
|
||||
|
||||
def test_conns_discovery(self):
|
||||
discovered_conns = discovery.IPSecConnectionsDiscovery().discover()
|
||||
self.assertEqual(1, len(discovered_conns))
|
||||
self.assertEqual(self.fake_get_ipsec_connections(), discovered_conns)
|
@ -62,6 +62,22 @@ sources:
|
||||
- "lb_members"
|
||||
sinks:
|
||||
- meter_sink
|
||||
- name: vpn_services_source
|
||||
interval: 600
|
||||
meters:
|
||||
- "network.services.vpn"
|
||||
discovery:
|
||||
- "vpn_services"
|
||||
sinks:
|
||||
- "meter_sink"
|
||||
- name: vpn_conns_source
|
||||
interval: 600
|
||||
meters:
|
||||
- "network.services.vpn.connections"
|
||||
discovery:
|
||||
- "ipsec_connections"
|
||||
sinks:
|
||||
- "meter_sink"
|
||||
sinks:
|
||||
- name: meter_sink
|
||||
transformers:
|
||||
|
@ -73,7 +73,8 @@ ceilometer.discover =
|
||||
lb_vips = ceilometer.network.services.discovery:LBVipsDiscovery
|
||||
lb_members = ceilometer.network.services.discovery:LBMembersDiscovery
|
||||
lb_health_probes = ceilometer.network.services.discovery:LBHealthMonitorsDiscovery
|
||||
|
||||
vpn_services = ceilometer.network.services.discovery:VPNServicesDiscovery
|
||||
ipsec_connections = ceilometer.network.services.discovery:IPSecConnectionsDiscovery
|
||||
|
||||
ceilometer.poll.compute =
|
||||
disk.read.requests = ceilometer.compute.pollsters.disk:ReadRequestsPollster
|
||||
@ -148,6 +149,9 @@ ceilometer.poll.central =
|
||||
network.services.lb.active.connections = ceilometer.network.services.lbaas:LBActiveConnectionsPollster
|
||||
network.services.lb.incoming.bytes = ceilometer.network.services.lbaas:LBBytesInPollster
|
||||
network.services.lb.outgoing.bytes = ceilometer.network.services.lbaas:LBBytesOutPollster
|
||||
network.services.vpn = ceilometer.network.services.vpnaas:VPNServicesPollster
|
||||
network.services.vpn.connections = ceilometer.network.services.vpnaas:IPSecConnectionsPollster
|
||||
|
||||
|
||||
ceilometer.alarm.storage =
|
||||
log = ceilometer.storage.impl_log:Connection
|
||||
|
Loading…
x
Reference in New Issue
Block a user