2023-11-28 18:58:57 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
|
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"google.golang.org/grpc"
|
2023-12-19 18:04:55 +00:00
|
|
|
"google.golang.org/grpc/credentials"
|
2023-11-28 18:58:57 +00:00
|
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
|
|
)
|
|
|
|
|
|
|
|
type GRPCClient struct {
|
|
|
|
Client pbresource.ResourceServiceClient
|
|
|
|
Config *GRPCConfig
|
|
|
|
Conn *grpc.ClientConn
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewGRPCClient(config *GRPCConfig) (*GRPCClient, error) {
|
|
|
|
conn, err := dial(config)
|
|
|
|
if err != nil {
|
2024-01-16 18:39:55 +00:00
|
|
|
return nil, fmt.Errorf("error dialing grpc: %+v", err)
|
2023-11-28 18:58:57 +00:00
|
|
|
}
|
|
|
|
return &GRPCClient{
|
|
|
|
Client: pbresource.NewResourceServiceClient(conn),
|
|
|
|
Config: config,
|
|
|
|
Conn: conn,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func dial(c *GRPCConfig) (*grpc.ClientConn, error) {
|
2023-12-19 18:04:55 +00:00
|
|
|
err := checkCertificates(c)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var dialOpts []grpc.DialOption
|
|
|
|
if c.GRPCTLS {
|
|
|
|
tlsConfig, err := SetupTLSConfig(c)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to setup tls config when tried to establish grpc call: %w", err)
|
|
|
|
}
|
|
|
|
dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
|
|
|
|
} else {
|
|
|
|
dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
2023-11-28 18:58:57 +00:00
|
|
|
}
|
2023-12-19 18:04:55 +00:00
|
|
|
|
2023-11-28 18:58:57 +00:00
|
|
|
return grpc.Dial(c.Address, dialOpts...)
|
|
|
|
}
|
2023-12-19 18:04:55 +00:00
|
|
|
|
|
|
|
func checkCertificates(c *GRPCConfig) error {
|
|
|
|
if c.GRPCTLS {
|
|
|
|
certFileEmpty := c.CertFile == ""
|
|
|
|
keyFileEmpty := c.CertFile == ""
|
|
|
|
|
|
|
|
// both files need to be empty or both files need to be provided
|
|
|
|
if certFileEmpty != keyFileEmpty {
|
|
|
|
return fmt.Errorf("you have to provide client certificate file and key file at the same time " +
|
|
|
|
"if you intend to communicate in TLS/SSL mode")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|