...

Source file src/github.com/letsencrypt/boulder/test/health-checker/main.go

Documentation: github.com/letsencrypt/boulder/test/health-checker

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"fmt"
     7  	"os"
     8  	"strings"
     9  	"time"
    10  
    11  	healthpb "google.golang.org/grpc/health/grpc_health_v1"
    12  
    13  	"github.com/letsencrypt/boulder/cmd"
    14  	bgrpc "github.com/letsencrypt/boulder/grpc"
    15  	"github.com/letsencrypt/boulder/metrics"
    16  )
    17  
    18  type config struct {
    19  	GRPC *cmd.GRPCClientConfig
    20  	TLS  *cmd.TLSConfig
    21  }
    22  
    23  func main() {
    24  	defer cmd.AuditPanic()
    25  
    26  	// Flag and config parsing and validation.
    27  	configFile := flag.String("config", "", "Path to the TLS configuration file")
    28  	serverAddr := flag.String("addr", "", "Address of the gRPC server to check")
    29  	flag.Parse()
    30  	if *configFile == "" {
    31  		flag.Usage()
    32  		os.Exit(1)
    33  	}
    34  
    35  	var c config
    36  	err := cmd.ReadConfigFile(*configFile, &c)
    37  	cmd.FailOnError(err, "failed to read json config")
    38  
    39  	if c.GRPC.ServerAddress == "" && *serverAddr == "" {
    40  		cmd.Fail("must specify either -addr flag or client.ServerAddress config")
    41  	} else if c.GRPC.ServerAddress != "" && *serverAddr != "" {
    42  		cmd.Fail("cannot specify both -addr flag and client.ServerAddress config")
    43  	} else if c.GRPC.ServerAddress == "" {
    44  		c.GRPC.ServerAddress = *serverAddr
    45  	}
    46  
    47  	tlsConfig, err := c.TLS.Load(metrics.NoopRegisterer)
    48  	cmd.FailOnError(err, "failed to load TLS credentials")
    49  
    50  	// GRPC connection prerequisites.
    51  	clk := cmd.Clock()
    52  
    53  	// Health check retry and timeout.
    54  	ticker := time.NewTicker(100 * time.Millisecond)
    55  	ctx, cancel := context.WithTimeout(context.Background(), 10*c.GRPC.Timeout.Duration)
    56  	defer cancel()
    57  
    58  	for {
    59  		select {
    60  		case <-ticker.C:
    61  			fmt.Fprintf(os.Stderr, "Connecting to %s health service\n", *serverAddr)
    62  			_, hostOverride, err := c.GRPC.MakeTargetAndHostOverride()
    63  			cmd.FailOnError(err, "")
    64  
    65  			// Set the hostOverride to match the dNSName in the server certificate.
    66  			c.GRPC.HostOverride = strings.Replace(hostOverride, ".service.consul", ".boulder", 1)
    67  
    68  			// Set up the GRPC connection.
    69  			conn, err := bgrpc.ClientSetup(c.GRPC, tlsConfig, metrics.NoopRegisterer, clk)
    70  			cmd.FailOnError(err, "failed to connect to service")
    71  			client := healthpb.NewHealthClient(conn)
    72  			ctx2, cancel2 := context.WithTimeout(ctx, c.GRPC.Timeout.Duration)
    73  			defer cancel2()
    74  
    75  			// Make the health check.
    76  			req := &healthpb.HealthCheckRequest{
    77  				Service: "",
    78  			}
    79  			resp, err := client.Check(ctx2, req)
    80  			if err != nil {
    81  				fmt.Fprintf(os.Stderr, "got error connecting to health service %s: %s\n", *serverAddr, err)
    82  			} else if resp.Status == healthpb.HealthCheckResponse_SERVING {
    83  				return
    84  			} else {
    85  				cmd.Fail(fmt.Sprintf("service %s failed health check with status %s", *serverAddr, resp.Status))
    86  			}
    87  
    88  		case <-ctx.Done():
    89  			cmd.Fail(fmt.Sprintf("timed out waiting for %s health check", *serverAddr))
    90  		}
    91  	}
    92  }
    93  

View as plain text