github.com/cilium/cilium@v1.16.2/pkg/hubble/peer/types/client.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package types
     5  
     6  import (
     7  	"context"
     8  	"crypto/tls"
     9  	"io"
    10  
    11  	"google.golang.org/grpc"
    12  	"google.golang.org/grpc/credentials"
    13  	"google.golang.org/grpc/credentials/insecure"
    14  
    15  	peerpb "github.com/cilium/cilium/api/v1/peer"
    16  	"github.com/cilium/cilium/pkg/crypto/certloader"
    17  	hubbleopts "github.com/cilium/cilium/pkg/hubble/server/serveroption"
    18  	"github.com/cilium/cilium/pkg/time"
    19  )
    20  
    21  // Client defines an interface that Peer service client should implement.
    22  type Client interface {
    23  	peerpb.PeerClient
    24  	io.Closer
    25  }
    26  
    27  // ClientBuilder creates a new Client.
    28  type ClientBuilder interface {
    29  	// Client builds a new Client that connects to the given target.
    30  	Client(target string) (Client, error)
    31  }
    32  
    33  type client struct {
    34  	conn *grpc.ClientConn
    35  	peerpb.PeerClient
    36  }
    37  
    38  func (c *client) Close() error {
    39  	if c.conn == nil {
    40  		return nil
    41  	}
    42  	return c.conn.Close()
    43  }
    44  
    45  // LocalClientBuilder is a ClientBuilder that is suitable when the gRPC
    46  // connection to the Peer service is local (typically a Unix Domain Socket).
    47  type LocalClientBuilder struct {
    48  	DialTimeout time.Duration
    49  }
    50  
    51  // Client implements ClientBuilder.Client.
    52  func (b LocalClientBuilder) Client(target string) (Client, error) {
    53  	ctx, cancel := context.WithTimeout(context.Background(), b.DialTimeout)
    54  	defer cancel()
    55  	// The connection is local, so we assume using insecure connection is safe in
    56  	// this context.
    57  	conn, err := grpc.DialContext(ctx, target,
    58  		grpc.WithTransportCredentials(insecure.NewCredentials()),
    59  		grpc.WithBlock())
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	return &client{conn, peerpb.NewPeerClient(conn)}, nil
    64  }
    65  
    66  // RemoteClientBuilder is a ClientBuilder that is suitable when the gRPC
    67  // connection to the Peer service is remote (typically a K8s Service).
    68  type RemoteClientBuilder struct {
    69  	DialTimeout   time.Duration
    70  	TLSConfig     certloader.ClientConfigBuilder
    71  	TLSServerName string
    72  }
    73  
    74  // Client implements ClientBuilder.Client.
    75  func (b RemoteClientBuilder) Client(target string) (Client, error) {
    76  	opts := []grpc.DialOption{grpc.WithBlock()}
    77  	if b.TLSConfig == nil {
    78  		opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
    79  	} else {
    80  		// NOTE: gosec is unable to resolve the constant and warns about "TLS
    81  		// MinVersion too low".
    82  		tlsConfig := b.TLSConfig.ClientConfig(&tls.Config{ //nolint:gosec
    83  			ServerName: b.TLSServerName,
    84  			MinVersion: hubbleopts.MinTLSVersion,
    85  		})
    86  		opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
    87  	}
    88  	ctx, cancel := context.WithTimeout(context.Background(), b.DialTimeout)
    89  	defer cancel()
    90  	conn, err := grpc.DialContext(ctx, target, opts...)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	return &client{conn, peerpb.NewPeerClient(conn)}, nil
    95  }