in internal/processmetrics/infra/infra.go [264:337]
func (p *Properties) collectUpcomingMaintenance(ctx context.Context) ([]*mrpb.TimeSeries, error) {
cp := p.Config.CloudProperties
project, zone, instName := cp.GetProjectId(), cp.GetZone(), cp.GetInstanceName()
// TODO : use the regular GCE service once the UpcomingMaintenance API
// is available there.
if p.gceBetaService == nil || !p.gceBetaService.Initialized() {
log.CtxLogger(ctx).Debug("compute beta API not initialized; skipping maint checks.")
return []*mrpb.TimeSeries{}, fmt.Errorf("compute beta API not initialized; skipping maint checks")
}
instance, err := p.gceBetaService.GetInstance(project, zone, instName)
if err != nil {
log.CtxLogger(ctx).Debugw("Could not get instance from compute API", "project", project, "zone", zone, "instance", instName, "error", err)
return []*mrpb.TimeSeries{}, fmt.Errorf("Could not get instance from compute API: %w", err)
}
log.CtxLogger(ctx).Debugw("Instance details", "type", instance.MachineType)
upM := &compute.UpcomingMaintenance{}
m := []*mrpb.TimeSeries{}
var metricsCollectionErr error
if instance.Scheduling == nil || len(instance.Scheduling.NodeAffinities) == 0 {
// Once the upcoming maintenance API is available in the GCE beta service,
// we might want to change the code to use the API directly - though maybe there is not
// much benefit in doing so.
log.CtxLogger(ctx).Debug("Not a sole tenant node; maintenance metric collection done via metadata server")
upcomingMaintenanceViaMS, err := p.collectUpcomingMaintenanceMS(ctx, upcomingMaintenanceMSCall)
if err != nil {
log.CtxLogger(ctx).Infow("Metadata server call", "error", err)
metricsCollectionErr = err
}
if upcomingMaintenanceViaMS != nil {
upM = upcomingMaintenanceViaMS
}
} else {
n, err := p.resolveNodeGroup(project, zone, instance.SelfLink)
if errors.Is(err, ErrNoStamMatch) {
return []*mrpb.TimeSeries{}, err
} else if err != nil {
log.CtxLogger(ctx).Debugw("Could not resolve node", "link", instance.SelfLink, "error", err)
return []*mrpb.TimeSeries{}, fmt.Errorf("could not resolve node: %w", err)
}
if n.UpcomingMaintenance == nil {
log.CtxLogger(ctx).Debugw("No upcoming maintenance", "cp", cp)
} else {
log.CtxLogger(ctx).Infof("Found upcoming maintenance: %+v", n.UpcomingMaintenance)
upM = n.UpcomingMaintenance
}
}
if _, ok := p.skippedMetrics[maintPath+"/can_reschedule"]; !ok {
m = append(m, p.createBoolMetric(maintPath+"/can_reschedule", upM.CanReschedule))
}
if _, ok := p.skippedMetrics[maintPath+"/type"]; !ok {
m = append(m, p.createIntMetric(maintPath+"/type", enumToInt(upM.Type, MaintenanceTypes)))
}
if _, ok := p.skippedMetrics[maintPath+"/maintenance_status"]; !ok {
m = append(m, p.createIntMetric(maintPath+"/maintenance_status", enumToInt(upM.MaintenanceStatus, MaintenanceStatuses)))
}
if _, ok := p.skippedMetrics[maintPath+"/window_start_time"]; !ok {
m = append(m, p.createIntMetric(maintPath+"/window_start_time", rfc3339ToUnix(upM.WindowStartTime)))
}
if _, ok := p.skippedMetrics[maintPath+"/window_end_time"]; !ok {
m = append(m, p.createIntMetric(maintPath+"/window_end_time", rfc3339ToUnix(upM.WindowEndTime)))
}
if _, ok := p.skippedMetrics[maintPath+"/latest_window_start_time"]; !ok {
m = append(m, p.createIntMetric(maintPath+"/latest_window_start_time", rfc3339ToUnix(upM.LatestWindowStartTime)))
}
return m, metricsCollectionErr
}