diff --git a/inventory_provider/config.py b/inventory_provider/config.py index 733877cc12a078b0579ae783dc9585d490471e63..cb0c95e658ea9818fa34e41d6823eb201fa01d49 100644 --- a/inventory_provider/config.py +++ b/inventory_provider/config.py @@ -117,7 +117,7 @@ CONFIG_SCHEMA = { 'required': ['tag', 'counters'], 'additionalProperties': False }, - 'gws-direct-host': { + 'gws-direct-host-v2': { 'type': 'object', 'properties': { 'hostname': {'type': 'string'}, @@ -131,6 +131,31 @@ CONFIG_SCHEMA = { 'required': ['hostname', 'community', 'interfaces'], 'additionalProperties': False }, + 'snmp-v3-cred': { + 'type': 'object', + 'properties': { + 'protocol': {'enum': ['MD5', 'DES']}, + 'password': {'type': 'string'} + }, + 'required': ['protocol', 'password'], + 'additionalProperties': False + }, + 'gws-direct-host-v3': { + 'type': 'object', + 'properties': { + 'hostname': {'type': 'string'}, + 'sec-name': {'type': 'string'}, + 'auth': {'$ref': '#/definitions/snmp-v3-cred'}, + 'priv': {'$ref': '#/definitions/snmp-v3-cred'}, + 'interfaces': { + 'type': 'array', + 'items': {'$ref': '#/definitions/gws-direct-interface'}, + 'minItems': 1 + } + }, + 'required': ['hostname', 'sec-name', 'interfaces'], + 'additionalProperties': False + }, 'gws-direct-nren-isp': { 'type': 'object', 'properties': { @@ -141,7 +166,12 @@ CONFIG_SCHEMA = { }, 'hosts': { 'type': 'array', - 'items': {'$ref': '#/definitions/gws-direct-host'}, + 'items': { + 'oneOf': [ + {'$ref': '#/definitions/gws-direct-host-v2'}, + {'$ref': '#/definitions/gws-direct-host-v3'}, + ] + }, 'minItems': 1 } }, diff --git a/inventory_provider/routes/poller.py b/inventory_provider/routes/poller.py index 10122a6727b042c6019f278b08c78c45cb89b404..10c3345fd1b5e38caf95c571731eb594f3a8900d 100644 --- a/inventory_provider/routes/poller.py +++ b/inventory_provider/routes/poller.py @@ -237,6 +237,33 @@ GWS_DIRECT_DATA_SCHEMA = { 'type': 'string', 'pattern': r'^(\d+\.)*\d+$' }, + 'snmp-v2': { + 'type': 'object', + 'properties': { + 'community': {'type': 'string'} + }, + 'required': ['community'], + 'additionalProperties': False + }, + 'snmp-v3-cred': { + 'type': 'object', + 'properties': { + 'protocol': {'enum': ['MD5', 'DES']}, + 'password': {'type': 'string'} + }, + 'required': ['protocol', 'password'], + 'additionalProperties': False + }, + 'snmp-v3': { + 'type': 'object', + 'properties': { + 'sec-name': {'type': 'string'}, + 'auth': {'$ref': '#/definitions/snmp-v3-cred'}, + 'priv': {'$ref': '#/definitions/snmp-v3-cred'} + }, + 'required': ['sec-name'], + 'additionalProperties': False + }, 'counter': { 'type': 'object', 'properties': { @@ -251,9 +278,14 @@ GWS_DIRECT_DATA_SCHEMA = { ] }, 'oid': {'$ref': '#/definitions/oid'}, - 'community': {'type': 'string'} + 'snmp': { + 'oneOf': [ + {'$ref': '#/definitions/snmp-v2'}, + {'$ref': '#/definitions/snmp-v3'} + ] + } }, - 'required': ['field', 'oid', 'community'], + 'required': ['field', 'oid', 'snmp'], 'additionalProperties': False }, 'interface-counters': { @@ -924,7 +956,24 @@ def gws_direct(): config_params = current_app.config['INVENTORY_PROVIDER_CONFIG'] for nren_isp in config_params['gws-direct']: for host in nren_isp['hosts']: + + snmp_params = {} + if 'community' in host: + # (snmp v2) + # sanity (already guaranteed by schema check) + assert 'sec-name' not in host + snmp_params['community'] = host['community'] + else: + # (snmp v3) + # sanity (already guaranteed by schema check) + assert 'sec-name' in host + snmp_params['sec-name'] = host['sec-name'] + if 'auth' in host: + snmp_params['auth'] = host['auth'] + if 'priv' in host: + snmp_params['priv'] = host['priv'] for ifc in host['interfaces']: + yield { 'nren': nren_isp['nren'], 'isp': nren_isp['isp'], @@ -934,8 +983,9 @@ def gws_direct(): { 'field': k, 'oid': v, - 'community': host['community'] - } for k, v in ifc['counters'].items()] + 'snmp': snmp_params + } + for k, v in ifc['counters'].items()] } result = json.dumps(list(_interfaces())) diff --git a/test/data/gws-direct.json b/test/data/gws-direct.json index db422736b59a697fda797b4a1f9390fc8f430ecd..3e399fc623f0ffa1481f8c90ed4075af08186918 100644 --- a/test/data/gws-direct.json +++ b/test/data/gws-direct.json @@ -285,5 +285,32 @@ ] } ] + }, + { + "nren": "HEANET", + "isp": "CenturyLink", + "hosts": [ + { + "hostname": "core2-cwt.nn.hea.net", + "sec-name": "abababab", + "auth": { + "protocol": "DES", + "password": "ccccddddccccdddd" + }, + "priv": { + "protocol": "MD5", + "password": "eeeeffffeeeeffff" + }, + "interfaces": [ + { + "tag": "a", + "counters": { + "traffic_in": "1.3.6.1.2.1.31.1.1.1.6.645", + "traffic_out": "1.3.6.1.2.1.31.1.1.1.10.645" + } + } + ] + } + ] } ] \ No newline at end of file diff --git a/test/test_general_poller_routes.py b/test/test_general_poller_routes.py index 7370c36cc0a2d1a1300e02f87f1c7a535a4d2e9d..571875bbeb6b0bb40c0ebf5727fd885fa5df57f3 100644 --- a/test/test_general_poller_routes.py +++ b/test/test_general_poller_routes.py @@ -4,8 +4,8 @@ import pytest from inventory_provider.routes import poller DEFAULT_REQUEST_HEADERS = { - "Content-type": "application/json", - "Accept": ["application/json"] + # 'Content-type': 'application/json', + 'Accept': ['application/json'] } @@ -43,7 +43,7 @@ def test_all_router_interface_speeds(client): headers=DEFAULT_REQUEST_HEADERS) assert rv.status_code == 200 - response = json.loads(rv.data.decode("utf-8")) + response = json.loads(rv.data.decode('utf-8')) jsonschema.validate(response, poller.INTERFACE_SPEED_LIST_SCHEMA) assert response # at least shouldn't be empty response_routers = {ifc['router'] for ifc in response}