95 lines
2.8 KiB
Go
95 lines
2.8 KiB
Go
|
package opnsense
|
||
|
|
||
|
import (
|
||
|
"github.com/go-kit/log"
|
||
|
"github.com/go-kit/log/level"
|
||
|
)
|
||
|
|
||
|
// gatewaysStatusResponse is the response from the OPNsense API that contains the gateways status details
|
||
|
// The data is constucted in this script:
|
||
|
// ---> https://github.com/opnsense/core/blob/master/src/opnsense/scripts/routes/gateway_status.php
|
||
|
// Following the reverse engineering of the call:
|
||
|
// ---> https://github.com/opnsense/core/blob/master/src/etc/inc/plugins.inc.d/dpinger.inc#L368
|
||
|
// From this file we know that Loss and Delay always have the same format of '%0.1f ms'
|
||
|
type gatewaysStatusResponse struct {
|
||
|
Items []struct {
|
||
|
Name string `json:"name"`
|
||
|
Address string `json:"address"`
|
||
|
Status string `json:"status"`
|
||
|
Loss string `json:"loss"`
|
||
|
Delay string `json:"delay"`
|
||
|
Stddev string `json:"stddev"`
|
||
|
StatusTranslated string `json:"status_translated"`
|
||
|
} `json:"items"`
|
||
|
Status string `json:"status"`
|
||
|
}
|
||
|
|
||
|
// GatewayStatus is the custom type that represents the status of a gateway
|
||
|
type GatewayStatus int
|
||
|
|
||
|
const (
|
||
|
GatewayStatusOffline GatewayStatus = iota
|
||
|
GatewayStatusOnline
|
||
|
GatewayStatusUnknown
|
||
|
)
|
||
|
|
||
|
type Gateway struct {
|
||
|
Name string
|
||
|
Address string
|
||
|
Status GatewayStatus
|
||
|
RTTMilliseconds float64
|
||
|
RTTDMilliseconds float64
|
||
|
LossPercentage float64
|
||
|
}
|
||
|
|
||
|
type Gateways struct {
|
||
|
Gateways []Gateway
|
||
|
}
|
||
|
|
||
|
// parseGatewayStatus parses a string status to a GatewayStatus type.
|
||
|
func parseGatewayStatus(statusTranslated string, logger log.Logger, originalStatus string) GatewayStatus {
|
||
|
switch statusTranslated {
|
||
|
case "Online":
|
||
|
return GatewayStatusOnline
|
||
|
case "Offline":
|
||
|
return GatewayStatusOffline
|
||
|
default:
|
||
|
level.Warn(logger).
|
||
|
Log("msg", "unknown gateway status detected", "status", originalStatus)
|
||
|
return GatewayStatusUnknown
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// FetchGateways fetches the gateways status details from the OPNsense API
|
||
|
// and returns a safe wrapper Gateways struct.
|
||
|
func (c *Client) FetchGateways() (Gateways, *APICallError) {
|
||
|
var resp gatewaysStatusResponse
|
||
|
var data Gateways
|
||
|
|
||
|
url, ok := c.endpoints["gatewaysStatus"]
|
||
|
if !ok {
|
||
|
return data, &APICallError{
|
||
|
Endpoint: "gatewaysStatus",
|
||
|
Message: "endpoint not found in client endpoints",
|
||
|
StatusCode: 0,
|
||
|
}
|
||
|
}
|
||
|
err := c.do("GET", url, nil, &resp)
|
||
|
if err != nil {
|
||
|
return data, err
|
||
|
}
|
||
|
|
||
|
for _, v := range resp.Items {
|
||
|
data.Gateways = append(data.Gateways, Gateway{
|
||
|
Name: v.Name,
|
||
|
Address: v.Address,
|
||
|
Status: parseGatewayStatus(v.StatusTranslated, c.log, v.Status),
|
||
|
RTTMilliseconds: parseStringToFloatWithReplace(v.Delay, c.gatewayRTTRegex, " ms", "rtt", c.log),
|
||
|
RTTDMilliseconds: parseStringToFloatWithReplace(v.Stddev, c.gatewayRTTRegex, " ms", "rttd", c.log),
|
||
|
LossPercentage: parseStringToFloatWithReplace(v.Loss, c.gatewayLossRegex, " %", "loss", c.log),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return data, nil
|
||
|
}
|