Skip to content

API expects device ID as query_location but IDs are not exposed via the API #139

Description

@syntax-terr0r

Bug Description

The following device is configured in hyperglass and returned by the API:

$ curl https://myhyperglass/api/devices | python -mjson.tool
[
    {
        "name": "router01.lab",
        "network": {
            "display_name": "AS1234",
            "name": "lab"
        },
        "vrfs": [
            {
                "display_name": "Global",
                "name": "global"
            }
        ]
    }
]

Attempting to query the device about a BGP route via the API results in an "invalid location" error:

$ curl -X POST https://myhyperglass/api/query/ -d     '{
        "query_location": "router01.lab",
        "query_type": "bgp_route",
        "query_vrf": "global",
        "query_target": "5.35.225.7"
    }' | python -mjson.tool
{
    "keywords": [
        "router01.lab",
        "Location"
    ],
    "level": "warning",
    "output": "router01.lab is an invalid Location."
}

Expected behavior

I would expect the API to return the same result as the web UI for that route.

Possible Solution

The problem seems to be that the query expects the device ID to be provided as the "query_location" instead of the device name:

    @validator("query_location")
    def validate_query_location(cls, value):
        """Ensure query_location is defined."""
        if value not in devices._ids:
            raise InputInvalid(
                params.messages.invalid_field,
                level="warning",
                input=value,
                field=params.web.text.query_location,
            )
        return value

When changing the "query_location" from the device name to the device ID (in this case stripping the "."), the query works as expected:

$ curl -X POST https://myhyperglass/api/query/ -d     '{
        "query_location": "router01lab",
        "query_type": "bgp_route",
        "query_vrf": "global",
        "query_target": "5.35.225.7"
    }' | python -mjson.tool
{
    "cached": false,
    "format": "application/json",
    "keywords": [],
    "level": "success",
    "output": {
        "count": 2,
        "routes": [
            {
                "active": true,
                "age": 2861860,
                "as_path": [],
                "communities": [
                    "no-advertise"
                ],
                "local_preference": 100,
                "med": 0,
                "next_hop": "10.30.30.9",
                "peer_rid": "1.2.3.4",
                "prefix": "5.35.225.7/32",
                "rpki_state": 3,
                "source_as": 0,
                "source_rid": "",
                "weight": 170
            }
        ],
        "vrf": "default",
        "winning_weight": "low"
    },
    "random": "77925c889d23b9fd9acc2ac9e3539e113c293d21ae6d9e18488ce88338f97439",
    "runtime": 9,
    "timestamp": "2021-05-10 11:53:58"
}

This is rather unintuitive however because /api/devices only returns the device names.
Looking at the UI which also uses the device names, you would expect the API to work the same way. I couldn't find any mention that the device ID had to be used in the API query.
In any case, it would be helpful if the device ID was exposed by /api/devices as well as the name so as to not having to do the translation on user side.
Alternatively the location validator could validate against the device name but that might be undesired.

Environment

Server

Metric Value
hyperglass Version 1.0.0-beta.82
hyperglass Path None
Python Version 3.6.8
Platform Info Linux-3.10.0-1160.25.1.el7.x86_64-x86_64-with-centos-7.9.2009-Core
CPU Info Intel Core Processor (Haswell, no TSX, IBRS)
Logical Cores 4
Physical Cores 4
Processor Speed 2.394454GHz
Total Memory 8.2 GB
Memory Utilization 29.4%
Total Disk Space 128.84 GB
Disk Utilization 7.0%

Metadata

Metadata

Assignees

Labels

acceptedIssue is confirmed and will be worked onbugConfirmed bug or unexpected behavior

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions