mirror of
https://github.com/linka-cloud/grpc.git
synced 2024-11-22 10:56:26 +00:00
212 lines
3.9 KiB
Go
212 lines
3.9 KiB
Go
package client
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"os"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
"go.linka.cloud/grpc-toolkit/interceptors"
|
|
"go.linka.cloud/grpc-toolkit/registry"
|
|
)
|
|
|
|
type Options interface {
|
|
Name() string
|
|
Version() string
|
|
Address() string
|
|
Secure() bool
|
|
Registry() registry.Registry
|
|
CA() string
|
|
Cert() string
|
|
Key() string
|
|
TLSConfig() *tls.Config
|
|
DialOptions() []grpc.DialOption
|
|
UnaryInterceptors() []grpc.UnaryClientInterceptor
|
|
StreamInterceptors() []grpc.StreamClientInterceptor
|
|
}
|
|
|
|
type Option func(*options)
|
|
|
|
func WithRegistry(registry registry.Registry) Option {
|
|
return func(o *options) {
|
|
o.registry = registry
|
|
}
|
|
}
|
|
|
|
func WithName(name string) Option {
|
|
return func(o *options) {
|
|
o.name = name
|
|
}
|
|
}
|
|
|
|
func WithVersion(version string) Option {
|
|
return func(o *options) {
|
|
o.version = version
|
|
}
|
|
}
|
|
|
|
func WithAddress(address string) Option {
|
|
return func(o *options) {
|
|
o.addr = address
|
|
}
|
|
}
|
|
|
|
func WithCA(ca string) Option {
|
|
return func(o *options) {
|
|
o.caCert = ca
|
|
}
|
|
}
|
|
|
|
func WithCert(cert string) Option {
|
|
return func(o *options) {
|
|
o.cert = cert
|
|
}
|
|
}
|
|
|
|
func WithKey(key string) Option {
|
|
return func(o *options) {
|
|
o.key = key
|
|
}
|
|
}
|
|
|
|
func WithTLSConfig(conf *tls.Config) Option {
|
|
return func(o *options) {
|
|
o.tlsConfig = conf
|
|
}
|
|
}
|
|
|
|
func WithSecure(s bool) Option {
|
|
return func(o *options) {
|
|
o.secure = s
|
|
}
|
|
}
|
|
|
|
func WithDialOptions(opts ...grpc.DialOption) Option {
|
|
return func(o *options) {
|
|
o.dialOptions = opts
|
|
}
|
|
}
|
|
|
|
func WithInterceptors(i ...interceptors.ClientInterceptors) Option {
|
|
return func(o *options) {
|
|
for _, v := range i {
|
|
o.unaryInterceptors = append(o.unaryInterceptors, v.UnaryClientInterceptor())
|
|
o.streamInterceptors = append(o.streamInterceptors, v.StreamClientInterceptor())
|
|
}
|
|
}
|
|
}
|
|
|
|
func WithUnaryInterceptors(i ...grpc.UnaryClientInterceptor) Option {
|
|
return func(o *options) {
|
|
o.unaryInterceptors = append(o.unaryInterceptors, i...)
|
|
}
|
|
}
|
|
|
|
func WithStreamInterceptors(i ...grpc.StreamClientInterceptor) Option {
|
|
return func(o *options) {
|
|
o.streamInterceptors = append(o.streamInterceptors, i...)
|
|
}
|
|
}
|
|
|
|
type options struct {
|
|
registry registry.Registry
|
|
name string
|
|
version string
|
|
addr string
|
|
|
|
caCert string
|
|
cert string
|
|
key string
|
|
tlsConfig *tls.Config
|
|
secure bool
|
|
dialOptions []grpc.DialOption
|
|
|
|
unaryInterceptors []grpc.UnaryClientInterceptor
|
|
streamInterceptors []grpc.StreamClientInterceptor
|
|
}
|
|
|
|
func (o *options) Name() string {
|
|
return o.name
|
|
}
|
|
|
|
func (o *options) Version() string {
|
|
return o.version
|
|
}
|
|
|
|
func (o *options) Address() string {
|
|
return o.addr
|
|
}
|
|
|
|
func (o *options) Registry() registry.Registry {
|
|
return o.registry
|
|
}
|
|
|
|
func (o *options) CA() string {
|
|
return o.caCert
|
|
}
|
|
|
|
func (o *options) Cert() string {
|
|
return o.cert
|
|
}
|
|
|
|
func (o *options) Key() string {
|
|
return o.key
|
|
}
|
|
|
|
func (o *options) TLSConfig() *tls.Config {
|
|
return o.tlsConfig
|
|
}
|
|
|
|
func (o *options) Secure() bool {
|
|
return o.secure
|
|
}
|
|
|
|
func (o *options) DialOptions() []grpc.DialOption {
|
|
return o.dialOptions
|
|
}
|
|
|
|
func (o *options) UnaryInterceptors() []grpc.UnaryClientInterceptor {
|
|
return o.unaryInterceptors
|
|
}
|
|
|
|
func (o *options) StreamInterceptors() []grpc.StreamClientInterceptor {
|
|
return o.streamInterceptors
|
|
}
|
|
|
|
func (o *options) hasTLSConfig() bool {
|
|
return o.caCert != "" && o.cert != "" && o.key != "" && o.tlsConfig == nil
|
|
}
|
|
|
|
func (o *options) parseTLSConfig() error {
|
|
if o.tlsConfig != nil {
|
|
return nil
|
|
}
|
|
if !o.hasTLSConfig() {
|
|
if !o.secure {
|
|
return nil
|
|
}
|
|
o.tlsConfig = &tls.Config{InsecureSkipVerify: true}
|
|
return nil
|
|
}
|
|
caCert, err := os.ReadFile(o.caCert)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
caCertPool := x509.NewCertPool()
|
|
ok := caCertPool.AppendCertsFromPEM(caCert)
|
|
if !ok {
|
|
return fmt.Errorf("failed to load CA Cert from %s", o.caCert)
|
|
}
|
|
cert, err := tls.LoadX509KeyPair(o.cert, o.key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
o.tlsConfig = &tls.Config{
|
|
Certificates: []tls.Certificate{cert},
|
|
RootCAs: caCertPool,
|
|
}
|
|
return nil
|
|
}
|