Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cisco/meraki): support webhook subscriptions for switch port up/down in existing Meraki Dashboard Driver #408

Open
w-le opened this issue Jan 10, 2023 · 2 comments

Comments

@w-le
Copy link
Contributor

w-le commented Jan 10, 2023

Extend existing Meraki driver to support webhook subscriptions for switch port up and down

Taken from a private internal solution design document authored by Will:

3.1.1.2 New Logic Driver: Meraki Switch Port Status

A new PlaceOS Logic Module will initially fetch the state of every switch port that we are interested in (switch port connected to a desk that is being monitored) and expose these as status variables.
The Logic module will use the existing Meraki Dashboard API driver to fetch the data.
Logic Module’s settings (inherited from System/Zones) will include an array of Network Switch serial strings (e.g. "Q2ZP-VE3T-JC2X")
For each switch, get all it’s ports’ status
GET /devices/{serial}/switch/ports/statuses
Example Response

[
    {
        "portId": "1",
        "enabled": true,
        "status": "Disconnected",
        "isUplink": false,
        "errors": [
            "Port disconnected"
        ],
        "warnings": [],
        "speed": "",
        "duplex": "",
        "usageInKb": {
            "total": 0,
            "sent": 0,
            "recv": 0
        },
        "cdp": {
            "platform": "Cisco CISCO1921/K9",
            "deviceId": "CPE-REDACTED-BRISBANE-9272.cpe.overthew",
            "portId": "GigabitEthernet0/1",
            "address": "10.1.74.66",
            "managementAddress": "10.1.74.66",
            "version": "Cisco IOS Software, C1900 Software (C1900-UNIVERSALK9-M), Version 15.6(3)M4, RELEASE SOFTWARE (fc1)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2018 by Cisco Systems, Inc.\nCompiled Mon 05-Feb-18 09:56 by prod_rel_team",
            "capabilities": "Router, Source route bridge, Switch"
        },
        "clientCount": 0,
        "powerUsageInWh": 0.0,
        "trafficInKbps": {
            "total": 0.0,
            "sent": 0.0,
            "recv": 0.0
        },
        "securePort": {
            "enabled": false,
            "active": false,
            "authenticationStatus": "Disabled",
            "configOverrides": {}
        }
    },
    {
        "portId": "11",
        "enabled": true,
        "status": "Connected",
        "isUplink": false,
        "errors": [],
        "warnings": [],
        "speed": "1 Gbps",
        "duplex": "full",
        "usageInKb": {
            "total": 615095,
            "sent": 380561,
            "recv": 234534
        },
        "lldp": {
            "portId": "REDACTED:MAC:ADDRESS",
            "chassisId": "REDACTED:MAC:ADDRESS"
        },
        "clientCount": 1,
        "powerUsageInWh": 0.0,
        "trafficInKbps": {
            "total": 58.3,
            "sent": 36.1,
            "recv": 22.2
        },
        "securePort": {
            "enabled": false,
            "active": false,
            "authenticationStatus": "Disabled",
            "configOverrides": {}
        }
    }
]

In order to unnecessary polling and reduce latency, the logic module (from 2) will subscribe to webhook updates from Meraki Dashboard API for:
Switch port has device connected
As seen from Dashboard API /organizations/:organizationId/webhooks/alertTypes

{
        "alertTypeId": "port_connected",
        "alertType": "Switch port connected",
        "example": {
            "version": "0.1",
            "sharedSecret": "secret",
            "sentAt": "2022-12-02T06:59:59.796865Z",
            "organizationId": "2930418",
            "organizationName": "My organization",
            "organizationUrl": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
            "networkId": "REDACTED",
            "networkName": "Main Office",
            "networkUrl": "https://n1.meraki.com//n//manage/nodes/list",
            "networkTags": [],
            "deviceSerial": "REDACTED",
            "deviceMac": "REDACTED:MAC:ADDRESS",
            "deviceName": "My switch",
            "deviceUrl": "https://n1.meraki.com//n//manage/nodes/new_list/000000000000",
            "deviceTags": [
                "tag1",
                "tag2"
            ],
            "deviceModel": "MS",
            "alertId": "0000000000000000",
            "alertType": "Switch port connected",
            "alertTypeId": "port_connected",
            "alertLevel": "informational",
            "occurredAt": "2018-02-11T00:00:00.123450Z",
            "alertData": {
                "portNum": 3,
                "description": "Switch port is up at 10 Gbps",
                "status": "10 Gbps",
                "prevStatus": "down",
                "portDesc": "Corp Access"
            },
            "enrollmentString": "my-enrollment-string",
            "notes": "Additional description of the network",
            "productTypes": [
                "appliance",
                "switch",
                "wireless"
            ]
        }

Switch port has device disconnected
As seen from Dashboard API /organizations/:organizationId/webhooks/alertTypes

{
        "alertTypeId": "port_disconnected",
        "alertType": "Switch port disconnected",
        "example": {
            "version": "0.1",
            "sharedSecret": "secret",
            "sentAt": "2022-12-02T06:59:59.806170Z",
            "organizationId": "2930418",
            "organizationName": "My organization",
            "organizationUrl": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
            "networkId": "N_24329156",
            "networkName": "Main Office",
            "networkUrl": "https://n1.meraki.com//n//manage/nodes/list",
            "networkTags": [],
            "deviceSerial": "Q234-ABCD-5678",
            "deviceMac": "00:11:22:33:44:55",
            "deviceName": "My switch",
            "deviceUrl": "https://n1.meraki.com//n//manage/nodes/new_list/000000000000",
            "deviceTags": [
                "tag1",
                "tag2"
            ],
            "deviceModel": "MS",
            "alertId": "0000000000000000",
            "alertType": "Switch port disconnected",
            "alertTypeId": "port_disconnected",
            "alertLevel": "warning",
            "occurredAt": "2018-02-11T00:00:00.123450Z",
            "alertData": {
                "portNum": 3,
                "description": "Switch port is down",
                "status": "down",
                "prevStatus": "100 Gbps",
                "portDesc": "Corp Access"
            },
            "enrollmentString": "my-enrollment-string",
            "notes": "Additional description of the network",
            "productTypes": [
                "appliance",
                "switch",
                "wireless"
            ]
        }

There are two scenarios in which the Logic driver must determine which USER (Azure AD User) is connected to the switch port:
After the initial poll of each switch’s port status (1.b)
There must then be a leap from the client mac address (from 1.b.ii lldp.portId) to the Meraki Client ID and description. The client.description is important for this particular implementation because the Meraki administrators have ensured that it matches the AAD User’s managedDevice’s deviceName. This will be done with GET /networks//clients?mac= which has example response:
[
{
"id": "ka44fb0",
"mac": "50:81:40:b1:96:c0",
"description": "XX-EBG8-12345",
"ip": "10.120.12.34",
"ip6": null,
"ip6Local": "fe80:0:0:0:683e:40bd:e0b:1234",
"user": null,
"firstSeen": "2021-10-20T23:28:22Z",
"lastSeen": "2022-12-05T11:59:32Z",
"manufacturer": "HP",
"os": null,
"deviceTypePrediction": null,
"recentDeviceSerial": "Q2ZP-VE3T-REDACTED",
"recentDeviceName": "REDACTED",
"recentDeviceMac": "ac:17:xx:52:76:xx",
"recentDeviceConnection": "Wired",
"ssid": null,
"vlan": "10",
"switchport": "11",
"usage": {
"sent": 190612,
"recv": 287176,
"total": 477789
},
"status": "Online",
"notes": "WS14/P75",
"smInstalled": false,
"groupPolicy8021x": null,
"adaptivePolicyGroup": null
}
]
When a “Port status: Connected” Webhook post is received (see section 3.1.1.1 point 3.d.ii.) from Meraki. See the example webhook data in 2.a.
Unfortunately there does not appear to be an API request available to get only the currently connected client’s details of a specific port of a Switch. So it appears we need to Get the status of all ports again (request 2a). We then locally filter for the port which changed to connected and use the client MAC in lldp.portId to determine the client data exactly as per 3.a.i.

@w-le w-le assigned grkek and unassigned stakach Jan 13, 2023
@w-le w-le changed the title feat(cisco/meraki): support webhook subscriptions for switch port up/down feat(cisco/meraki): support webhook subscriptions for switch port up/down in existing Meraki Dashboard Driver Jan 16, 2023
@w-le
Copy link
Contributor Author

w-le commented Jan 17, 2023

@stakach has added support for receiving the webhook POST, in #412

There appears to be no way to create new webhook subscriptions via API calls, so we will have provide instructions to the meraki admin to post to us.

So there are no outstanding items related to webhooks. And the only remaining items for this gh issue are:

  1. Adding a new func to GET /devices/{serial}/switch/ports/statuses (REST GET, not webhook).
  2. Adding a new func to GET /networks//clients?mac= (see internal solution design doc section 3.1.1.2 bullet point 3.a.i

Correct me if I'm wrong on any of the above @stakach

@w-le w-le assigned stakach and unassigned grkek Jan 18, 2023
@w-le w-le assigned w-le and unassigned stakach Feb 2, 2023
@w-le w-le added the status: requires testing Requires Testing label Feb 2, 2023
@w-le
Copy link
Contributor Author

w-le commented Feb 2, 2023

deployed. poll works. webhook to be tested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants