Skip to content

Commit

Permalink
Merge pull request #39 from grafana/feat/grpc
Browse files Browse the repository at this point in the history
Feature: Add gRPC related packages
  • Loading branch information
aknuds1 authored Oct 7, 2021
2 parents a105bb3 + 321c579 commit 1ae630c
Show file tree
Hide file tree
Showing 21 changed files with 965 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
* [CHANGE] Removed global metrics for KV package. Making a KV object will now require a prometheus registerer that will be used to register all relevant KV class metrics. #22
* [CHANGE] Added CHANGELOG.md and Pull Request template to reference the changelog
* [CHANGE] Remove `cortex_` prefix for metrics registered in the ring. #46
* [CHANGE] Rename `kv/kvtls` to `crypto/tls`. #39
* [ENHANCEMENT] Add middleware package. #38
* [ENHANCEMENT] Add limiter package. #41
* [ENHANCEMENT] Add grpcclient, grpcencoding and grpcutil packages. #39
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ import (
"google.golang.org/grpc/keepalive"

"github.com/grafana/dskit/backoff"
"github.com/grafana/dskit/kv/kvtls"
"github.com/grafana/dskit/crypto/tls"
)

type tcIntegrationClientServer struct {
name string
tlsGrpcEnabled bool
tlsConfig kvtls.ClientConfig
tlsConfig tls.ClientConfig
httpExpectError func(*testing.T, error)
grpcExpectError func(*testing.T, error)
}
Expand Down Expand Up @@ -183,14 +183,14 @@ func TestServerWithoutTlsEnabled(t *testing.T) {
[]tcIntegrationClientServer{
{
name: "no-config",
tlsConfig: kvtls.ClientConfig{},
tlsConfig: tls.ClientConfig{},
httpExpectError: errorContainsString("http: server gave HTTP response to HTTPS client"),
grpcExpectError: nil,
},
{
name: "tls-enable",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{},
tlsConfig: tls.ClientConfig{},
httpExpectError: errorContainsString("http: server gave HTTP response to HTTPS client"),
grpcExpectError: errorContainsString("transport: authentication handshake failed: tls: first record does not look like a TLS handshake"),
},
Expand Down Expand Up @@ -218,44 +218,44 @@ func TestServerWithLocalhostCertNoClientCertAuth(t *testing.T) {
[]tcIntegrationClientServer{
{
name: "no-config",
tlsConfig: kvtls.ClientConfig{},
tlsConfig: tls.ClientConfig{},
httpExpectError: errorContainsString("x509: certificate signed by unknown authority"),
// For GRPC we expect this error as we try to connect without TLS to a TLS enabled server
grpcExpectError: unavailableDescErr,
},
{
name: "grpc-tls-enabled",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{},
tlsConfig: tls.ClientConfig{},
httpExpectError: errorContainsString("x509: certificate signed by unknown authority"),
grpcExpectError: errorContainsString("x509: certificate signed by unknown authority"),
},
{
name: "tls-skip-verify",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
InsecureSkipVerify: true,
},
},
{
name: "tls-skip-verify-no-grpc-tls-enabled",
tlsGrpcEnabled: false,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
InsecureSkipVerify: true,
},
grpcExpectError: unavailableDescErr,
},
{
name: "ca-path-set",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
},
},
{
name: "ca-path-no-grpc-tls-enabled",
tlsGrpcEnabled: false,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
},
grpcExpectError: unavailableDescErr,
Expand Down Expand Up @@ -283,22 +283,22 @@ func TestServerWithoutLocalhostCertNoClientCertAuth(t *testing.T) {
[]tcIntegrationClientServer{
{
name: "no-config",
tlsConfig: kvtls.ClientConfig{},
tlsConfig: tls.ClientConfig{},
httpExpectError: errorContainsString("x509: certificate is valid for my-other-name, not localhost"),
// For GRPC we expect this error as we try to connect without TLS to a TLS enabled server
grpcExpectError: unavailableDescErr,
},
{
name: "grpc-tls-enabled",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{},
tlsConfig: tls.ClientConfig{},
httpExpectError: errorContainsString("x509: certificate is valid for my-other-name, not localhost"),
grpcExpectError: errorContainsString("x509: certificate is valid for my-other-name, not localhost"),
},
{
name: "ca-path",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
},
httpExpectError: errorContainsString("x509: certificate is valid for my-other-name, not localhost"),
Expand All @@ -307,15 +307,15 @@ func TestServerWithoutLocalhostCertNoClientCertAuth(t *testing.T) {
{
name: "server-name",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
ServerName: "my-other-name",
},
},
{
name: "tls-skip-verify",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
InsecureSkipVerify: true,
},
},
Expand Down Expand Up @@ -352,7 +352,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "tls-skip-verify",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
InsecureSkipVerify: true,
},
httpExpectError: badCertErr,
Expand All @@ -361,7 +361,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "ca-path",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
},
httpExpectError: badCertErr,
Expand All @@ -370,7 +370,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "ca-path-and-client-cert-ca1",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
CertPath: certs.client1CertFile,
KeyPath: certs.client1KeyFile,
Expand All @@ -379,7 +379,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "tls-skip-verify-and-client-cert-ca1",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
InsecureSkipVerify: true,
CertPath: certs.client1CertFile,
KeyPath: certs.client1KeyFile,
Expand All @@ -388,7 +388,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "ca-cert-and-client-cert-ca2",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
CertPath: certs.client2CertFile,
KeyPath: certs.client2KeyFile,
Expand Down Expand Up @@ -423,7 +423,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "ca-cert-and-client-cert-ca1",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
CertPath: certs.client1CertFile,
KeyPath: certs.client1KeyFile,
Expand All @@ -432,7 +432,7 @@ func TestTLSServerWithLocalhostCertWithClientCertificateEnforcementUsingClientCA
{
name: "ca-cert-and-client-cert-ca2",
tlsGrpcEnabled: true,
tlsConfig: kvtls.ClientConfig{
tlsConfig: tls.ClientConfig{
CAPath: certs.caCertFile,
CertPath: certs.client2CertFile,
KeyPath: certs.client2KeyFile,
Expand Down Expand Up @@ -577,8 +577,8 @@ type grpcConfig struct {
BackoffOnRatelimits bool `yaml:"backoff_on_ratelimits"`
BackoffConfig backoff.Config `yaml:"backoff_config"`

TLSEnabled bool `yaml:"tls_enabled"`
TLS kvtls.ClientConfig `yaml:",inline"`
TLSEnabled bool `yaml:"tls_enabled"`
TLS tls.ClientConfig `yaml:",inline"`
}

// RegisterFlags registers flags.
Expand Down
2 changes: 1 addition & 1 deletion kv/kvtls/tls.go → crypto/tls/tls.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kvtls
package tls

import (
"crypto/tls"
Expand Down
25 changes: 10 additions & 15 deletions kv/kvtls/tls_test.go → crypto/tls/tls_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package kvtls
package tls

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -70,32 +69,28 @@ type x509Paths struct {
}

func newTestX509Files(t *testing.T, cert, key, ca []byte) x509Paths {
// create empty file
certsPath, err := ioutil.TempDir("", "*-x509")
require.NoError(t, err)
t.Helper()

t.Cleanup(func() {
os.RemoveAll(certsPath)
})
certsPath := t.TempDir()

paths := x509Paths{
cert: fmt.Sprintf("%s/cert.pem", certsPath),
key: fmt.Sprintf("%s/key.pem", certsPath),
ca: fmt.Sprintf("%s/ca.pem", certsPath),
cert: filepath.Join(certsPath, "cert.pem"),
key: filepath.Join(certsPath, "key.pem"),
ca: filepath.Join(certsPath, "ca.pem"),
}

if cert != nil {
err = ioutil.WriteFile(paths.cert, cert, 0600)
err := os.WriteFile(paths.cert, cert, 0600)
require.NoError(t, err)
}

if key != nil {
err = ioutil.WriteFile(paths.key, key, 0600)
err := os.WriteFile(paths.key, key, 0600)
require.NoError(t, err)
}

if ca != nil {
err = ioutil.WriteFile(paths.ca, ca, 0600)
err := os.WriteFile(paths.ca, ca, 0600)
require.NoError(t, err)
}

Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ require (
github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-sockaddr v1.0.2
github.com/hashicorp/memberlist v0.2.3
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e
github.com/opentracing/opentracing-go v1.2.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/common v0.26.0
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xC
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/api v1.9.1 h1:SngrdG2L62qqLsUz85qcPhFZ78rPf8tcD5qjMgs6MME=
github.com/hashicorp/consul/api v1.9.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
Expand Down Expand Up @@ -304,8 +305,9 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q=
github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc=
github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg=
github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9 h1:QsgXACQhd9QJhEmRumbsMQQvBtmdS0mafoVEBplWXEg=
github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
Expand Down Expand Up @@ -495,6 +497,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand Down
31 changes: 31 additions & 0 deletions grpcclient/backoff_retry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package grpcclient

import (
"context"

"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/grafana/dskit/backoff"
)

// NewBackoffRetry gRPC middleware.
func NewBackoffRetry(cfg backoff.Config) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
backoff := backoff.New(ctx, cfg)
for backoff.Ongoing() {
err := invoker(ctx, method, req, reply, cc, opts...)
if err == nil {
return nil
}

if status.Code(err) != codes.ResourceExhausted {
return err
}

backoff.Wait()
}
return backoff.Err()
}
}
Loading

0 comments on commit 1ae630c

Please sign in to comment.