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

replaced /msr/access-services by more general method

/msr/access-services is now an internal call to
/poller/services/geant_ip
parent 35739b30
No related branches found
No related tags found
No related merge requests found
...@@ -4,18 +4,13 @@ MSR Support Endpoints ...@@ -4,18 +4,13 @@ MSR Support Endpoints
These endpoints are intended for use by MSR. These endpoints are intended for use by MSR.
.. contents:: :local:
/msr/access-services
---------------------------------
.. autofunction:: inventory_provider.routes.msr.access_services
.. contents:: :local:
/msr/gws-indirect /poller/access-services
--------------------------------- ---------------------------------
.. autofunction:: inventory_provider.routes.msr.gws_indirect .. autofunction::inventory_provider.routes.msr.get_access_services
/msr/bgp/logical-systems /msr/bgp/logical-systems
...@@ -68,36 +63,11 @@ from flask import Blueprint, Response, request ...@@ -68,36 +63,11 @@ from flask import Blueprint, Response, request
from inventory_provider.routes import common from inventory_provider.routes import common
from inventory_provider.routes.common import _ignore_cache_or_retrieve from inventory_provider.routes.common import _ignore_cache_or_retrieve
from inventory_provider.routes.poller import get_services
routes = Blueprint('msr-query-routes', __name__) routes = Blueprint('msr-query-routes', __name__)
ACCESS_SERVICES_LIST_SCHEMA = {
'$schema': 'http://json-schema.org/draft-07/schema#',
'definitions': {
'service': {
'type': 'object',
'properties': {
'id': {'type': 'integer'},
'name': {'type': 'string'},
'customer': {'type': 'string'},
'speed': {'type': 'integer'},
'pop': {'type': 'string'},
'hostname': {'type': 'string'},
'interface': {'type': 'string'},
},
'required': [
'id', 'name', 'customer', 'speed',
'pop', 'hostname', 'interface'],
'additionalProperties': False
}
},
'type': 'array',
'items': {'$ref': '#/definitions/service'}
}
PEERING_GROUP_LIST_SCHEMA = { PEERING_GROUP_LIST_SCHEMA = {
'$schema': 'http://json-schema.org/draft-07/schema#', '$schema': 'http://json-schema.org/draft-07/schema#',
'type': 'array', 'type': 'array',
...@@ -141,111 +111,6 @@ def after_request(resp): ...@@ -141,111 +111,6 @@ def after_request(resp):
return common.after_request(resp) return common.after_request(resp)
@routes.route('/access-services', methods=['GET', 'POST'])
@common.require_accepts_json
def access_services():
"""
Handler for `/msr/access-services`.
This method is in development, not yet used.
The response will be formatted according to the following schema:
.. asjson::
inventory_provider.routes.msr.ACCESS_SERVICES_LIST_SCHEMA
:return:
"""
redis = common.get_current_redis()
def _services():
for k in redis.scan_iter('ims:services:access_services:*'):
service = redis.get(k.decode('utf-8')).decode('utf-8')
service = json.loads(service)
yield {
'id': service['id'],
'name': service['name'],
'customer': service['project'],
'speed': service['speed_value'],
'pop': service['here']['pop']['name'],
'hostname': common.ims_equipment_to_hostname(
service['here']['equipment']),
'interface': service['here']['port']
}
cache_key = 'classifier-cache:msr:access-services'
result = _ignore_cache_or_retrieve(request, cache_key, redis)
if not result:
result = list(_services())
if not result:
return Response(
response='no access services found',
status=404,
mimetype='text/html')
# cache this data for the next call
result = json.dumps(result)
redis.set(cache_key, result.encode('utf-8'))
return Response(result, mimetype='application/json')
@routes.route('/gws-indirect', methods=['GET', 'POST'])
@common.require_accepts_json
def gws_indirect():
"""
Handler for `/msr/gws-indirect`.
This method is in development, not yet used.
The response will be formatted according to the following schema:
.. asjson::
inventory_provider.routes.msr.ACCESS_SERVICES_LIST_SCHEMA
:return:
"""
redis = common.get_current_redis()
def _services():
for k in redis.scan_iter('ims:services:gws_indirect:*'):
service = redis.get(k.decode('utf-8')).decode('utf-8')
service = json.loads(service)
yield {
'id': service['id'],
'name': service['name'],
'customer': service['project'],
'speed': service['speed_value'],
'pop': service['here']['pop']['name'],
'hostname': common.ims_equipment_to_hostname(
service['here']['equipment']),
'interface': service['here']['port']
}
cache_key = 'classifier-cache:msr:gws-indirect'
result = _ignore_cache_or_retrieve(request, cache_key, redis)
if not result:
result = list(_services())
if not result:
return Response(
response='no gws indirect services found',
status=404,
mimetype='text/html')
# cache this data for the next call
result = json.dumps(result)
redis.set(cache_key, result.encode('utf-8'))
return Response(result, mimetype='application/json')
def _handle_peering_group_request(name, cache_key, group_key_base): def _handle_peering_group_request(name, cache_key, group_key_base):
""" """
Common method for used by Common method for used by
...@@ -449,3 +314,16 @@ def get_peering_routing_instances(): ...@@ -449,3 +314,16 @@ def get_peering_routing_instances():
return _handle_peering_group_list_request( return _handle_peering_group_list_request(
cache_key='classifier-cache:msr:routing-instances', cache_key='classifier-cache:msr:routing-instances',
group_key_base='juniper-peerings:routing-instance') group_key_base='juniper-peerings:routing-instance')
@routes.route('/access-services', methods=['GET', 'POST'])
@common.require_accepts_json
def get_access_services():
"""
Handler for `/msr/access-services`
Same as `/poller/services/geant_ip`
cf. :meth:`inventory_provider.routes.poller.get_services`
"""
return get_services(service_type='geant_ip')
...@@ -29,6 +29,13 @@ These endpoints are intended for use by BRIAN. ...@@ -29,6 +29,13 @@ These endpoints are intended for use by BRIAN.
.. autofunction:: inventory_provider.routes.poller.gws_direct .. autofunction:: inventory_provider.routes.poller.gws_direct
/poller/services</type>
---------------------------------
.. autofunction:: inventory_provider.routes.poller.get_services
""" """
import json import json
import logging import logging
...@@ -203,6 +210,33 @@ GWS_DIRECT_DATA_SCHEMA = { ...@@ -203,6 +210,33 @@ GWS_DIRECT_DATA_SCHEMA = {
} }
SERVICES_LIST_SCHEMA = {
'$schema': 'http://json-schema.org/draft-07/schema#',
'definitions': {
'service': {
'type': 'object',
'properties': {
'id': {'type': 'integer'},
'name': {'type': 'string'},
'customer': {'type': 'string'},
'speed': {'type': 'integer'},
'pop': {'type': 'string'},
'hostname': {'type': 'string'},
'interface': {'type': 'string'},
},
'required': [
'id', 'name', 'customer', 'speed',
'pop', 'hostname', 'interface'],
'additionalProperties': False
}
},
'type': 'array',
'items': {'$ref': '#/definitions/service'}
}
@routes.after_request @routes.after_request
def after_request(resp): def after_request(resp):
return common.after_request(resp) return common.after_request(resp)
...@@ -662,3 +696,69 @@ def gws_direct(): ...@@ -662,3 +696,69 @@ def gws_direct():
r.set(cache_key, result.encode('utf-8')) r.set(cache_key, result.encode('utf-8'))
return Response(result, mimetype="application/json") return Response(result, mimetype="application/json")
@routes.route('/services', methods=['GET', 'POST'])
@routes.route('/services/<service_type>', methods=['GET', 'POST'])
@common.require_accepts_json
def get_services(service_type=None):
"""
Handler for `/poller/services/type`.
The response will be formatted according to the following schema:
.. asjson::
inventory_provider.routes.poller.SERVICES_LIST_SCHEMA
:return:
"""
def _services():
key_pattern = f'ims:services:{service_type}:*' \
if service_type else 'ims:services:*'
for doc in common.load_json_docs(
config_params=current_app.config['INVENTORY_PROVIDER_CONFIG'],
key_pattern=key_pattern,
num_threads=20):
yield doc['value']
def _operational(s):
return s['status'].lower() == 'operational'
def _format_services(s):
return {
'id': s['id'],
'name': s['name'],
'customer': s['project'],
'speed': s['speed_value'],
'pop': s['here']['pop']['name'],
'hostname': common.ims_equipment_to_hostname(
s['here']['equipment']),
'interface': s['here']['port']
}
cache_key = f'classifier-cache:poller:services:{service_type}' \
if service_type else 'classifier-cache:poller:services:all'
redis = common.get_current_redis()
result = _ignore_cache_or_retrieve(request, cache_key, redis)
if not result:
result = _services()
result = filter(_operational, result)
result = map(_format_services, result)
result = list(result)
if not result:
message = f'no {service_type} services found' \
if service_type else 'no services found'
return Response(
response=message,
status=404,
mimetype='text/html')
# cache this data for the next call
result = json.dumps(result)
redis.set(cache_key, result.encode('utf-8'))
return Response(result, mimetype='application/json')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment