grpc_proxy.go (etcd-3.5.5) | : | grpc_proxy.go (etcd-3.5.6) | ||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
"math" | "math" | |||
"net" | "net" | |||
"net/http" | "net/http" | |||
"net/url" | "net/url" | |||
"os" | "os" | |||
"path/filepath" | "path/filepath" | |||
"time" | "time" | |||
pb "go.etcd.io/etcd/api/v3/etcdserverpb" | pb "go.etcd.io/etcd/api/v3/etcdserverpb" | |||
"go.etcd.io/etcd/client/pkg/v3/logutil" | "go.etcd.io/etcd/client/pkg/v3/logutil" | |||
"go.etcd.io/etcd/client/pkg/v3/tlsutil" | ||||
"go.etcd.io/etcd/client/pkg/v3/transport" | "go.etcd.io/etcd/client/pkg/v3/transport" | |||
clientv3 "go.etcd.io/etcd/client/v3" | clientv3 "go.etcd.io/etcd/client/v3" | |||
"go.etcd.io/etcd/client/v3/leasing" | "go.etcd.io/etcd/client/v3/leasing" | |||
"go.etcd.io/etcd/client/v3/namespace" | "go.etcd.io/etcd/client/v3/namespace" | |||
"go.etcd.io/etcd/client/v3/ordering" | "go.etcd.io/etcd/client/v3/ordering" | |||
"go.etcd.io/etcd/pkg/v3/debugutil" | "go.etcd.io/etcd/pkg/v3/debugutil" | |||
"go.etcd.io/etcd/server/v3/embed" | "go.etcd.io/etcd/server/v3/embed" | |||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3election/v3electionpb" | "go.etcd.io/etcd/server/v3/etcdserver/api/v3election/v3electionpb" | |||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3lock/v3lockpb" | "go.etcd.io/etcd/server/v3/etcdserver/api/v3lock/v3lockpb" | |||
"go.etcd.io/etcd/server/v3/proxy/grpcproxy" | "go.etcd.io/etcd/server/v3/proxy/grpcproxy" | |||
"go.uber.org/zap/zapgrpc" | ||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" | grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" | |||
"github.com/soheilhy/cmux" | "github.com/soheilhy/cmux" | |||
"github.com/spf13/cobra" | "github.com/spf13/cobra" | |||
"go.uber.org/zap" | "go.uber.org/zap" | |||
"go.uber.org/zap/zapgrpc" | ||||
"golang.org/x/net/http2" | "golang.org/x/net/http2" | |||
"google.golang.org/grpc" | "google.golang.org/grpc" | |||
"google.golang.org/grpc/grpclog" | "google.golang.org/grpc/grpclog" | |||
"google.golang.org/grpc/keepalive" | "google.golang.org/grpc/keepalive" | |||
) | ) | |||
var ( | var ( | |||
grpcProxyListenAddr string | grpcProxyListenAddr string | |||
grpcProxyMetricsListenAddr string | grpcProxyMetricsListenAddr string | |||
grpcProxyEndpoints []string | grpcProxyEndpoints []string | |||
skipping to change at line 77 | skipping to change at line 78 | |||
// tls for connecting to etcd | // tls for connecting to etcd | |||
grpcProxyCA string | grpcProxyCA string | |||
grpcProxyCert string | grpcProxyCert string | |||
grpcProxyKey string | grpcProxyKey string | |||
grpcProxyInsecureSkipTLSVerify bool | grpcProxyInsecureSkipTLSVerify bool | |||
// tls for clients connecting to proxy | // tls for clients connecting to proxy | |||
grpcProxyListenCA string | grpcProxyListenCA string | |||
grpcProxyListenCert string | grpcProxyListenCert string | |||
grpcProxyListenKey string | grpcProxyListenKey string | |||
grpcProxyListenAutoTLS bool | grpcProxyListenCipherSuites []string | |||
grpcProxyListenCRL string | grpcProxyListenAutoTLS bool | |||
selfSignedCertValidity uint | grpcProxyListenCRL string | |||
selfSignedCertValidity uint | ||||
grpcProxyAdvertiseClientURL string | grpcProxyAdvertiseClientURL string | |||
grpcProxyResolverPrefix string | grpcProxyResolverPrefix string | |||
grpcProxyResolverTTL int | grpcProxyResolverTTL int | |||
grpcProxyNamespace string | grpcProxyNamespace string | |||
grpcProxyLeasing string | grpcProxyLeasing string | |||
grpcProxyEnablePprof bool | grpcProxyEnablePprof bool | |||
grpcProxyEnableOrdering bool | grpcProxyEnableOrdering bool | |||
skipping to change at line 157 | skipping to change at line 159 | |||
// client TLS for connecting to server | // client TLS for connecting to server | |||
cmd.Flags().StringVar(&grpcProxyCert, "cert", "", "identify secure connec tions with etcd servers using this TLS certificate file") | cmd.Flags().StringVar(&grpcProxyCert, "cert", "", "identify secure connec tions with etcd servers using this TLS certificate file") | |||
cmd.Flags().StringVar(&grpcProxyKey, "key", "", "identify secure connecti ons with etcd servers using this TLS key file") | cmd.Flags().StringVar(&grpcProxyKey, "key", "", "identify secure connecti ons with etcd servers using this TLS key file") | |||
cmd.Flags().StringVar(&grpcProxyCA, "cacert", "", "verify certificates of TLS-enabled secure etcd servers using this CA bundle") | cmd.Flags().StringVar(&grpcProxyCA, "cacert", "", "verify certificates of TLS-enabled secure etcd servers using this CA bundle") | |||
cmd.Flags().BoolVar(&grpcProxyInsecureSkipTLSVerify, "insecure-skip-tls-v erify", false, "skip authentication of etcd server TLS certificates (CAUTION: th is option should be enabled only for testing purposes)") | cmd.Flags().BoolVar(&grpcProxyInsecureSkipTLSVerify, "insecure-skip-tls-v erify", false, "skip authentication of etcd server TLS certificates (CAUTION: th is option should be enabled only for testing purposes)") | |||
// client TLS for connecting to proxy | // client TLS for connecting to proxy | |||
cmd.Flags().StringVar(&grpcProxyListenCert, "cert-file", "", "identify se cure connections to the proxy using this TLS certificate file") | cmd.Flags().StringVar(&grpcProxyListenCert, "cert-file", "", "identify se cure connections to the proxy using this TLS certificate file") | |||
cmd.Flags().StringVar(&grpcProxyListenKey, "key-file", "", "identify secu re connections to the proxy using this TLS key file") | cmd.Flags().StringVar(&grpcProxyListenKey, "key-file", "", "identify secu re connections to the proxy using this TLS key file") | |||
cmd.Flags().StringVar(&grpcProxyListenCA, "trusted-ca-file", "", "verify certificates of TLS-enabled secure proxy using this CA bundle") | cmd.Flags().StringVar(&grpcProxyListenCA, "trusted-ca-file", "", "verify certificates of TLS-enabled secure proxy using this CA bundle") | |||
cmd.Flags().StringSliceVar(&grpcProxyListenCipherSuites, "listen-cipher-s uites", grpcProxyListenCipherSuites, "Comma-separated list of supported TLS ciph er suites between client/proxy (empty will be auto-populated by Go).") | ||||
cmd.Flags().BoolVar(&grpcProxyListenAutoTLS, "auto-tls", false, "proxy TL S using generated certificates") | cmd.Flags().BoolVar(&grpcProxyListenAutoTLS, "auto-tls", false, "proxy TL S using generated certificates") | |||
cmd.Flags().StringVar(&grpcProxyListenCRL, "client-crl-file", "", "proxy client certificate revocation list file.") | cmd.Flags().StringVar(&grpcProxyListenCRL, "client-crl-file", "", "proxy client certificate revocation list file.") | |||
cmd.Flags().UintVar(&selfSignedCertValidity, "self-signed-cert-validity", 1, "The validity period of the proxy certificates, unit is year") | cmd.Flags().UintVar(&selfSignedCertValidity, "self-signed-cert-validity", 1, "The validity period of the proxy certificates, unit is year") | |||
// experimental flags | // experimental flags | |||
cmd.Flags().BoolVar(&grpcProxyEnableOrdering, "experimental-serializable- ordering", false, "Ensure serializable reads have monotonically increasing store revisions across endpoints.") | cmd.Flags().BoolVar(&grpcProxyEnableOrdering, "experimental-serializable- ordering", false, "Ensure serializable reads have monotonically increasing store revisions across endpoints.") | |||
cmd.Flags().StringVar(&grpcProxyLeasing, "experimental-leasing-prefix", " ", "leasing metadata prefix for disconnected linearized reads.") | cmd.Flags().StringVar(&grpcProxyLeasing, "experimental-leasing-prefix", " ", "leasing metadata prefix for disconnected linearized reads.") | |||
cmd.Flags().BoolVar(&grpcProxyDebug, "debug", false, "Enable debug-level logging for grpc-proxy.") | cmd.Flags().BoolVar(&grpcProxyDebug, "debug", false, "Enable debug-level logging for grpc-proxy.") | |||
skipping to change at line 190 | skipping to change at line 193 | |||
if err != nil { | if err != nil { | |||
panic(err) | panic(err) | |||
} | } | |||
defer lg.Sync() | defer lg.Sync() | |||
grpclog.SetLoggerV2(zapgrpc.NewLogger(lg)) | grpclog.SetLoggerV2(zapgrpc.NewLogger(lg)) | |||
// The proxy itself (ListenCert) can have not-empty CN. | // The proxy itself (ListenCert) can have not-empty CN. | |||
// The empty CN is required for grpcProxyCert. | // The empty CN is required for grpcProxyCert. | |||
// Please see https://github.com/etcd-io/etcd/issues/11970#issuecomment-6 87875315 for more context. | // Please see https://github.com/etcd-io/etcd/issues/11970#issuecomment-6 87875315 for more context. | |||
tlsinfo := newTLS(grpcProxyListenCA, grpcProxyListenCert, grpcProxyListen | tlsInfo := newTLS(grpcProxyListenCA, grpcProxyListenCert, grpcProxyListen | |||
Key, false) | Key, false) | |||
if len(grpcProxyListenCipherSuites) > 0 { | ||||
if tlsinfo == nil && grpcProxyListenAutoTLS { | cs, err := tlsutil.GetCipherSuites(grpcProxyListenCipherSuites) | |||
if err != nil { | ||||
log.Fatal(err) | ||||
} | ||||
tlsInfo.CipherSuites = cs | ||||
} | ||||
if tlsInfo == nil && grpcProxyListenAutoTLS { | ||||
host := []string{"https://" + grpcProxyListenAddr} | host := []string{"https://" + grpcProxyListenAddr} | |||
dir := filepath.Join(grpcProxyDataDir, "fixtures", "proxy") | dir := filepath.Join(grpcProxyDataDir, "fixtures", "proxy") | |||
autoTLS, err := transport.SelfCert(lg, dir, host, selfSignedCertV alidity) | autoTLS, err := transport.SelfCert(lg, dir, host, selfSignedCertV alidity) | |||
if err != nil { | if err != nil { | |||
log.Fatal(err) | log.Fatal(err) | |||
} | } | |||
tlsinfo = &autoTLS | tlsInfo = &autoTLS | |||
} | } | |||
if tlsinfo != nil { | ||||
lg.Info("gRPC proxy server TLS", zap.String("tls-info", fmt.Sprin | if tlsInfo != nil { | |||
tf("%+v", tlsinfo))) | lg.Info("gRPC proxy server TLS", zap.String("tls-info", fmt.Sprin | |||
tf("%+v", tlsInfo))) | ||||
} | } | |||
m := mustListenCMux(lg, tlsinfo) | m := mustListenCMux(lg, tlsInfo) | |||
grpcl := m.Match(cmux.HTTP2()) | grpcl := m.Match(cmux.HTTP2()) | |||
defer func() { | defer func() { | |||
grpcl.Close() | grpcl.Close() | |||
lg.Info("stop listening gRPC proxy client requests", zap.String(" address", grpcProxyListenAddr)) | lg.Info("stop listening gRPC proxy client requests", zap.String(" address", grpcProxyListenAddr)) | |||
}() | }() | |||
client := mustNewClient(lg) | client := mustNewClient(lg) | |||
// The proxy client is used for self-healthchecking. | // The proxy client is used for self-healthchecking. | |||
// TODO: The mechanism should be refactored to use internal connection. | // TODO: The mechanism should be refactored to use internal connection. | |||
var proxyClient *clientv3.Client | var proxyClient *clientv3.Client | |||
if grpcProxyAdvertiseClientURL != "" { | if grpcProxyAdvertiseClientURL != "" { | |||
proxyClient = mustNewProxyClient(lg, tlsinfo) | proxyClient = mustNewProxyClient(lg, tlsInfo) | |||
} | } | |||
httpClient := mustNewHTTPClient(lg) | httpClient := mustNewHTTPClient(lg) | |||
srvhttp, httpl := mustHTTPListener(lg, m, tlsinfo, client, proxyClient) | srvhttp, httpl := mustHTTPListener(lg, m, tlsInfo, client, proxyClient) | |||
if err := http2.ConfigureServer(srvhttp, &http2.Server{ | if err := http2.ConfigureServer(srvhttp, &http2.Server{ | |||
MaxConcurrentStreams: maxConcurrentStreams, | MaxConcurrentStreams: maxConcurrentStreams, | |||
}); err != nil { | }); err != nil { | |||
lg.Fatal("Failed to configure the http server", zap.Error(err)) | lg.Fatal("Failed to configure the http server", zap.Error(err)) | |||
} | } | |||
errc := make(chan error, 3) | errc := make(chan error, 3) | |||
go func() { errc <- newGRPCProxyServer(lg, client).Serve(grpcl) }() | go func() { errc <- newGRPCProxyServer(lg, client).Serve(grpcl) }() | |||
go func() { errc <- srvhttp.Serve(httpl) }() | go func() { errc <- srvhttp.Serve(httpl) }() | |||
go func() { errc <- m.Serve() }() | go func() { errc <- m.Serve() }() | |||
if len(grpcProxyMetricsListenAddr) > 0 { | if len(grpcProxyMetricsListenAddr) > 0 { | |||
mhttpl := mustMetricsListener(lg, tlsinfo) | mhttpl := mustMetricsListener(lg, tlsInfo) | |||
go func() { | go func() { | |||
mux := http.NewServeMux() | mux := http.NewServeMux() | |||
grpcproxy.HandleMetrics(mux, httpClient, client.Endpoints ()) | grpcproxy.HandleMetrics(mux, httpClient, client.Endpoints ()) | |||
grpcproxy.HandleHealth(lg, mux, client) | grpcproxy.HandleHealth(lg, mux, client) | |||
grpcproxy.HandleProxyMetrics(mux) | grpcproxy.HandleProxyMetrics(mux) | |||
grpcproxy.HandleProxyHealth(lg, mux, proxyClient) | grpcproxy.HandleProxyHealth(lg, mux, proxyClient) | |||
lg.Info("gRPC proxy server metrics URL serving") | lg.Info("gRPC proxy server metrics URL serving") | |||
herr := http.Serve(mhttpl, mux) | herr := http.Serve(mhttpl, mux) | |||
if herr != nil { | if herr != nil { | |||
lg.Fatal("gRPC proxy server metrics URL returned" , zap.Error(herr)) | lg.Fatal("gRPC proxy server metrics URL returned" , zap.Error(herr)) | |||
End of changes. 12 change blocks. | ||||
19 lines changed or deleted | 29 lines changed or added |