Skip to content
Snippets Groups Projects
Commit c046f888 authored by Erik Reid's avatar Erik Reid
Browse files

added snmp info to responses

parent 5d2a55d6
Branches
Tags
No related merge requests found
......@@ -259,7 +259,7 @@ def load_xml_docs(config_params, key_pattern, num_threads=10):
yield from _load_redis_docs(
config_params, key_pattern, num_threads, doc_type=_DECODE_TYPE_XML)
@functools.lru_cache
def load_snmp_indexes(hostname=None):
result = dict()
key_pattern = f'snmp-interfaces:{hostname}*' \
......
......@@ -49,6 +49,7 @@ These endpoints are intended for use by BRIAN.
"""
import functools
import json
import logging
import re
......@@ -227,6 +228,15 @@ SERVICES_LIST_SCHEMA = {
'$schema': 'http://json-schema.org/draft-07/schema#',
'definitions': {
'snmp-info': {
'type': 'object',
'properties': {
'ifIndex': {'type': 'integer'},
'community': {'type': 'string'}
},
'required': ['ifIndex', 'community'],
'additionalProperties': False
},
'service': {
'type': 'object',
'properties': {
......@@ -238,7 +248,8 @@ SERVICES_LIST_SCHEMA = {
'hostname': {'type': 'string'},
'interface': {'type': 'string'},
'type': {'type': 'string'},
'status': {'type': 'string'}
'status': {'type': 'string'},
'snmp': {'$ref': '#/definitions/snmp-info'}
},
'required': [
'id', 'name', 'customer',
......@@ -721,6 +732,7 @@ def gws_direct():
return Response(result, mimetype="application/json")
def _get_services_internal(service_type=None):
"""
Performs the lookup and caching done for calls to
......@@ -740,6 +752,7 @@ def _get_services_internal(service_type=None):
"""
return_all = common.get_bool_request_arg('all', False)
include_snmp = common.get_bool_request_arg('snmp', False)
def _services():
key_pattern = f'ims:services:{service_type}:*' \
......@@ -751,6 +764,17 @@ def _get_services_internal(service_type=None):
num_threads=20):
yield doc['value']
def _add_snmp(s):
all_snmp_info = common.load_snmp_indexes()
snmp_interfaces = all_snmp_info.get(s['hostname'], {})
interface_info = snmp_interfaces.get(s['interface'], None)
if interface_info:
s['snmp'] = {
'ifIndex': interface_info['index'],
'community': interface_info['community']
}
return s
def _wanted_in_output(s):
return return_all or (s['status'].lower() == 'operational')
......@@ -763,7 +787,7 @@ def _get_services_internal(service_type=None):
'pop': s['here']['pop']['name'],
'hostname': common.ims_equipment_to_hostname(
s['here']['equipment']),
'interface': s['here']['port'],
'interface': s['here']['port'].lower(),
'type': s['type'],
'status': s['status']
}
......@@ -773,6 +797,8 @@ def _get_services_internal(service_type=None):
if return_all:
cache_key = f'{cache_key}:all'
if include_snmp:
cache_key = f'{cache_key}:snmp'
redis = common.get_current_redis()
result = _ignore_cache_or_retrieve(request, cache_key, redis)
......@@ -781,6 +807,8 @@ def _get_services_internal(service_type=None):
result = _services()
result = filter(_wanted_in_output, result)
result = map(_format_services, result)
if include_snmp:
result = map(_add_snmp, result)
result = list(result)
if not result:
......@@ -804,6 +832,15 @@ def get_services(service_type=None):
If the endpoint is called with no `service-type`,
all services are returned.
Supported url parameters:
:all: Default is False to return only operational services.
If present and evaluates to True, then return all services.
:snmp: If present and evalutes to True, add snmp interface polling
params to the response.
(sphinx bug: the param names aren't capitalized)
The response will be formatted according to the following schema:
.. asjson::
......@@ -855,6 +892,10 @@ def get_service_types():
can be used with `/poller/services/service-type` to return
a non-empty list of services.
Adding a truthy `all` request parameter (e.g. `?all=1`) will
return also return valid service types for which none of the
defined services are operational.
The response will be formatted according to the following schema:
.. asjson::
......
......@@ -102,6 +102,24 @@ def test_all_services_all(client):
assert response_data # test data is non-empty
assert any(s['status'] != 'operational' for s in response_data)
assert all('snmp' not in s for s in response_data)
@pytest.mark.parametrize('service_type',
# services with these types should all have snmp configs
['gws_indirect', 'geant_ip', 'l3_vpn'])
def test_services_snmp(client, service_type):
rv = client.get(
f'/poller/services/{service_type}?snmp=1',
headers=DEFAULT_REQUEST_HEADERS)
assert rv.status_code == 200
assert rv.is_json
response_data = json.loads(rv.data.decode('utf-8'))
jsonschema.validate(response_data, poller.SERVICES_LIST_SCHEMA)
assert response_data # test data is non-empty
# all access services should have snmp info
assert all('snmp' in s for s in response_data)
@pytest.mark.parametrize('uri_type,expected_type', [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment