github.com/m-lab/locate@v0.17.6/cmd/heartbeat/health/gcp.go (about) 1 package health 2 3 import ( 4 "context" 5 "strings" 6 7 "cloud.google.com/go/compute/apiv1/computepb" 8 "github.com/googleapis/gax-go" 9 ) 10 11 // GCPChecker queries the VM's load balancer to check its status. 12 type GCPChecker struct { 13 client GCEClient 14 md Metadata 15 } 16 17 // Metadata returns environmental metadata for a machine. 18 type Metadata interface { 19 Project() string 20 Backend() string 21 Region() string 22 Group() string 23 } 24 25 // GCEClient queries the Compute API for health updates. 26 type GCEClient interface { 27 GetHealth(context.Context, *computepb.GetHealthRegionBackendServiceRequest, ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error) 28 } 29 30 // NewGCPChecker returns a new instance of GCPChecker. 31 func NewGCPChecker(c GCEClient, md Metadata) *GCPChecker { 32 return &GCPChecker{ 33 client: c, 34 md: md, 35 } 36 } 37 38 // GetHealth contacts the GCP load balancer to get the latest VM health status 39 // and uses the data to generate a health score. 40 func (c *GCPChecker) GetHealth(ctx context.Context) float64 { 41 g := c.md.Group() 42 req := &computepb.GetHealthRegionBackendServiceRequest{ 43 BackendService: c.md.Backend(), 44 Project: c.md.Project(), 45 Region: c.md.Region(), 46 ResourceGroupReferenceResource: &computepb.ResourceGroupReference{ 47 Group: &g, 48 }, 49 } 50 lbHealth, err := c.client.GetHealth(ctx, req) 51 if err != nil { 52 return 0 53 } 54 55 for _, h := range lbHealth.HealthStatus { 56 // The group is healthy if at least one of the instances has a 'HEALTHY' health state. 57 if strings.EqualFold(*h.HealthState, "HEALTHY") { 58 return 1 59 } 60 } 61 62 return 0 63 }