go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers-sdk/v1/upstream/health/health.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package health
     5  
     6  import (
     7  	"context"
     8  	"net/http"
     9  	"time"
    10  )
    11  
    12  //go:generate protoc --proto_path=. --go_out=. --go_opt=paths=source_relative --rangerrpc_out=. health.proto
    13  
    14  type Status struct {
    15  	API struct {
    16  		Endpoint  string `json:"endpoint,omitempty"`
    17  		Status    string `json:"status,omitempty"`
    18  		Timestamp string `json:"timestamp,omitempty"`
    19  		Version   string `json:"version,omitempty"`
    20  	} `json:"api,omitempty"`
    21  	Features []string `json:"features,omitempty"`
    22  	Warnings []string `json:"warnings,omitempty"`
    23  }
    24  
    25  func CheckApiHealth(httpClient *http.Client, endpoint string) (Status, error) {
    26  	status := Status{}
    27  	status.API.Endpoint = endpoint
    28  
    29  	sendTime := time.Now()
    30  	healthClient, err := NewHealthClient(endpoint, httpClient)
    31  	if err != nil {
    32  		return status, err
    33  	}
    34  	healthResp, err := healthClient.Check(context.Background(), &HealthCheckRequest{})
    35  	if err != nil {
    36  		return status, err
    37  	} else {
    38  		status.API.Status = healthResp.Status.String()
    39  		status.API.Timestamp = healthResp.Time
    40  		status.API.Version = healthResp.ApiVersion
    41  
    42  		// do time check to make it easier to detect ssl/tls issues
    43  		receivedResponseTime := time.Now()
    44  		roundTripDuration := receivedResponseTime.Sub(sendTime)
    45  		if roundTripDuration > time.Second*5 {
    46  			status.Warnings = append(status.Warnings, "detected very long round-trip times: "+roundTripDuration.String())
    47  		}
    48  
    49  		upstream, err := time.Parse(time.RFC3339, healthResp.Time)
    50  		if err != nil {
    51  			status.Warnings = append(status.Warnings, "cannot run clock skew check")
    52  		} else {
    53  			diff := upstream.Sub(sendTime)
    54  			if abs(diff) > time.Second*30 {
    55  				status.Warnings = append(status.Warnings, "possible clock skew detected: "+diff.String())
    56  			}
    57  		}
    58  	}
    59  	return status, nil
    60  }
    61  
    62  func abs(a time.Duration) time.Duration {
    63  	if a >= 0 {
    64  		return a
    65  	}
    66  	return -a
    67  }