github.com/grafana/synthetic-monitoring-agent@v0.64.2/cmd/synthetic-monitoring-agent/grpc.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"log"
     7  	"strings"
     8  
     9  	"github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
    10  	"google.golang.org/grpc"
    11  	"google.golang.org/grpc/credentials"
    12  	"google.golang.org/grpc/credentials/insecure"
    13  	"google.golang.org/grpc/keepalive"
    14  )
    15  
    16  // newAPIServerClient creates a client connection to an API server. It does not
    17  // block: grpc.NewClient returns immediately with the connection in IDLE and
    18  // connects lazily in the background on the first RPC.
    19  func newAPIServerClient(addr string, allowInsecure bool, apiToken string) (*grpc.ClientConn, error) {
    20  	apiCreds := creds{Token: apiToken}
    21  
    22  	opts := []grpc.DialOption{
    23  		grpc.WithPerRPCCredentials(apiCreds),
    24  		// Keep-alive is necessary to detect network failures in absence of writes from the client.
    25  		// Without it, the agent would hang if the server disappears while waiting for a response.
    26  		// See https://github.com/grpc/grpc/blob/master/doc/keepalive.md
    27  		grpc.WithKeepaliveParams(keepalive.ClientParameters{
    28  			// GRPC_ARG_KEEPALIVE_TIME_MS - Time between pings
    29  			Time: synthetic_monitoring.HealthCheckInterval,
    30  			// GRPC_ARG_KEEPALIVE_TIMEOUT_MS - Ping timeout
    31  			Timeout: synthetic_monitoring.HealthCheckTimeout,
    32  			// GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS - Allow pings even if no grpc calls are in place.
    33  			// It shouldn't be the case that the agent doesn't have any calls in place during
    34  			// a significant period of time.
    35  			PermitWithoutStream: true,
    36  		}),
    37  	}
    38  
    39  	transportCreds := insecure.NewCredentials()
    40  	if !allowInsecure {
    41  		transportCreds = credentials.NewTLS(&tls.Config{ServerName: grpcApiHost(addr)})
    42  	}
    43  
    44  	opts = append(opts, grpc.WithTransportCredentials(transportCreds))
    45  
    46  	return grpc.NewClient(addr, opts...)
    47  }
    48  
    49  func grpcApiHost(addr string) string {
    50  	colonPos := strings.LastIndex(addr, ":")
    51  	if colonPos == -1 {
    52  		colonPos = len(addr)
    53  	}
    54  
    55  	hostname := addr[:colonPos]
    56  
    57  	return hostname
    58  }
    59  
    60  type creds struct {
    61  	Token string
    62  }
    63  
    64  func (c creds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
    65  	return map[string]string{
    66  		"authorization": "Bearer " + c.Token,
    67  	}, nil
    68  }
    69  
    70  func (c creds) RequireTransportSecurity() bool {
    71  	log.Printf("RequireTransportSecurity")
    72  	// XXX(mem): this is true
    73  	return false
    74  }