diff --git a/inventory_provider/__init__.py b/inventory_provider/__init__.py index adbe82909a290cab265ec936fc225d68201076c3..6068a9d4ac62368fdd23234e8a4d4958d625003d 100644 --- a/inventory_provider/__init__.py +++ b/inventory_provider/__init__.py @@ -43,6 +43,13 @@ def create_app(): app.config['INVENTORY_PROVIDER_CONFIG'] = inventory_provider_config + # IMS based routes + + from inventory_provider.routes import ims_lg + app.register_blueprint(ims_lg.routes, url_prefix='/ims-lg') + + # end of IMS based routes + from inventory_provider.routes import default app.register_blueprint(default.routes, url_prefix='/') diff --git a/inventory_provider/config.py b/inventory_provider/config.py index 4311d91c9aaa6217001d01dea1cc5fd75b8931c6..1709f4b0186f6e34c5a432e9854576b8f00ae9d1 100644 --- a/inventory_provider/config.py +++ b/inventory_provider/config.py @@ -68,6 +68,16 @@ CONFIG_SCHEMA = { "api": {"type": "string"}, "username": {"type": "string"}, "password": {"type": "string"} + }, + "otrs-export": { + "username": {"type": "string"}, + "private-key": {"type": "string"}, + "destination": {"type": "string"} + }, + "ims": { + "api": {"type": "string"}, + "username": {"type": "string"}, + "password": {"type": "string"} } }, "oneOf": [ @@ -77,7 +87,8 @@ CONFIG_SCHEMA = { "ssh", "redis", "redis-databases", - "junosspace"] + "junosspace", + "ims"] }, { "required": [ @@ -85,7 +96,8 @@ CONFIG_SCHEMA = { "ssh", "sentinel", "redis-databases", - "junosspace"] + "junosspace", + "ims"] } ], "additionalProperties": False diff --git a/inventory_provider/routes/ims_lg.py b/inventory_provider/routes/ims_lg.py new file mode 100644 index 0000000000000000000000000000000000000000..79d7930287796f664b30a78d90dfb396e2f12f93 --- /dev/null +++ b/inventory_provider/routes/ims_lg.py @@ -0,0 +1,60 @@ +import json + +from flask import Blueprint, jsonify, Response + +from inventory_provider.routes import common + +routes = Blueprint("ims-lg-query-routes", __name__) + +ACCESS_PUBLIC = 'public' +ACCESS_INTERNAL = 'all' + + +@routes.after_request +def after_request(resp): + return common.after_request(resp) + + +@routes.route("/routers/<string:access>", methods=['GET', 'POST']) +@common.require_accepts_json +def routers(access): + + if access not in {ACCESS_INTERNAL, ACCESS_PUBLIC}: + return Response( + response='unknown access level', + status=404, + mimetype='text/html') + + redis = common.get_current_redis() + + def _visible(router): + if access == ACCESS_INTERNAL: + return True + return router['type'] == 'CORE' + + def _routers(): + i = 0 + for k in redis.scan_iter(f'ims:lg:*'): + rtr = redis.get(k.decode('utf-8')).decode('utf-8') + rtr = json.loads(rtr) + i += 1 + if _visible(rtr): + yield rtr + + cache_key = f'classifier-cache:ims-lg:{access}' + result = redis.get(cache_key) + + if result: + result = json.loads(result.decode('utf-8')) + else: + result = list(_routers()) + # cache this data for the next call + redis.set(cache_key, json.dumps(result).encode('utf-8')) + + if not result: + return Response( + response=f'no routers found for access level {access}', + status=404, + mimetype="text/html") + + return jsonify(result) diff --git a/inventory_provider/routes/testing.py b/inventory_provider/routes/testing.py index 45fdd056b5f5dbe4f7df4ac9d947db4f4ff0caaa..b94f7f2cedcb8ed98b3888319115fa4cd3a04a14 100644 --- a/inventory_provider/routes/testing.py +++ b/inventory_provider/routes/testing.py @@ -7,7 +7,7 @@ from lxml import etree from inventory_provider import juniper from inventory_provider.routes import common -from inventory_provider.tasks import worker +from inventory_provider.tasks import worker, ims_worker from inventory_provider.tasks import common as worker_common routes = Blueprint("inventory-data-testing-support-routes", __name__) @@ -19,6 +19,16 @@ def flushdb(): return Response('OK') +# IMS routes + +@routes.route("update-lg-routers-ims", methods=['GET', 'POST']) +def update_lg_routers_ims(): + ims_worker.update_lg_routers_ims.delay() + return Response('OK') + +# End of IMS routes + + @routes.route("update-interfaces-to-services", methods=['GET', 'POST']) def update_interfaces_to_services(): worker.update_interfaces_to_services.delay() diff --git a/inventory_provider/tasks/ims_worker.py b/inventory_provider/tasks/ims_worker.py new file mode 100644 index 0000000000000000000000000000000000000000..47fe69ff15b427c5068ceeac8d4409c64eafceff --- /dev/null +++ b/inventory_provider/tasks/ims_worker.py @@ -0,0 +1,34 @@ +import csv +import json +import logging +import subprocess +import tempfile +from datetime import datetime +from pathlib import Path + +from inventory_provider.db import ims_data +from inventory_provider.db.ims import IMS +from inventory_provider import environment +from inventory_provider.tasks.app import app +from inventory_provider.tasks.common import get_next_redis +from inventory_provider.tasks.worker import InventoryTask + +environment.setup_logging() + +logger = logging.getLogger(__name__) + + +@app.task(base=InventoryTask, bind=True) +def update_lg_routers_ims(self): + logger.debug('>>> update_lg_routers_ims - MOVED') + + r = get_next_redis(InventoryTask.config) + for k in r.scan_iter('ims:lg:*'): + r.delete(k) + c = InventoryTask.config["ims"] + ds = IMS(c['api'], c['username'], c['password']) + + for router in ims_data.lookup_lg_routers(ds): + r.set(f'ims:lg:{router["equipment name"]}', json.dumps(router)) + + logger.debug('<<< update_lg_routers_ims') diff --git a/test/conftest.py b/test/conftest.py index 7ed4586b067d4144eb9c6a30d6790a02da415f8e..f7f2d8c0b1d4e22ec25760ff59a4741ce5f59f0b 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -46,7 +46,12 @@ def data_config_filename(): "api": "bogus-url", "username": "bogus-username", "password": "bogus-password" - } + }, + "ims": { + "api": "dummy", + "username": "dummy", + "password": "dummy" + } } f.write(json.dumps(config).encode('utf-8'))