in x-pack/metricbeat/module/meraki/device_health/uplinks.go [25:121]
func getDeviceUplinks(client *meraki.Client, organizationID string, devices map[Serial]*Device, period time.Duration) error {
// there are two separate APIs for uplink statuses depending on the type of device (MG or MX/Z).
// there is a single API for getting the loss and latency metrics regardless of the type of device.
// in this function we combine loss and latency metrics with device-specific status information,
// and attach it to the relevant device in the supplied `devices` data structure.
applicanceUplinks, res, err := client.Appliance.GetOrganizationApplianceUplinkStatuses(organizationID, &meraki.GetOrganizationApplianceUplinkStatusesQueryParams{})
if err != nil {
return fmt.Errorf("GetOrganizationApplianceUplinkStatuses failed; [%d] %s. %w", res.StatusCode(), res.Body(), err)
}
lossAndLatency, res, err := client.Organizations.GetOrganizationDevicesUplinksLossAndLatency(
organizationID,
&meraki.GetOrganizationDevicesUplinksLossAndLatencyQueryParams{
Timespan: period.Seconds(),
},
)
if err != nil {
return fmt.Errorf("GetOrganizationDevicesUplinksLossAndLatency failed; [%d] %s. %w", res.StatusCode(), res.Body(), err)
}
if applicanceUplinks == nil || lossAndLatency == nil {
return errors.New("unexpected response from Meraki API: applicanceUplinks or lossAndLatency is nil")
}
for _, device := range *applicanceUplinks {
deviceObj, ok := devices[Serial(device.Serial)]
if device.HighAvailability != nil && ok && deviceObj != nil {
devices[Serial(device.Serial)].haStatus = device.HighAvailability
}
if device.Uplinks != nil {
var uplinks []*uplink
for i := range *device.Uplinks {
uplinkStatus := (*device.Uplinks)[i]
uplink := &uplink{
lastReportedAt: device.LastReportedAt,
status: &uplinkStatus,
}
for j := range *lossAndLatency {
metrics := (*lossAndLatency)[j]
if metrics.TimeSeries != nil && metrics.Serial == device.Serial && metrics.Uplink == uplinkStatus.Interface {
uplink.lossAndLatency = &metrics
break
}
}
uplinks = append(uplinks, uplink)
}
if ok && deviceObj != nil {
devices[Serial(device.Serial)].uplinks = uplinks
}
}
}
cellularGatewayUplinks, res, err := client.CellularGateway.GetOrganizationCellularGatewayUplinkStatuses(organizationID, &meraki.GetOrganizationCellularGatewayUplinkStatusesQueryParams{})
if err != nil {
return fmt.Errorf("GetOrganizationCellularGatewayUplinkStatuses failed; [%d] %s. %w", res.StatusCode(), res.Body(), err)
}
if cellularGatewayUplinks == nil {
return errors.New("unexpected response from Meraki API: cellularGatewayUplinks is nil")
}
for _, device := range *cellularGatewayUplinks {
if device.Uplinks == nil {
continue
}
var uplinks []*uplink
for i := range *device.Uplinks {
uplinkStatus := (*device.Uplinks)[i]
uplink := &uplink{
lastReportedAt: device.LastReportedAt,
cellularGatewayStatus: &uplinkStatus,
}
for j := range *lossAndLatency {
metrics := (*lossAndLatency)[j]
if metrics.TimeSeries != nil && metrics.Serial == device.Serial && metrics.Uplink == uplinkStatus.Interface {
uplink.lossAndLatency = &metrics
break
}
}
uplinks = append(uplinks, uplink)
}
deviceObj, ok := devices[Serial(device.Serial)]
if ok && deviceObj != nil {
devices[Serial(device.Serial)].uplinks = uplinks
}
}
return nil
}