Skip to content

Commit

Permalink
Enable gRPC server reflection to agent workload endpoints (spiffe#4916)
Browse files Browse the repository at this point in the history
* Add reflection to agent workload endpoints

Signed-off-by: Guilherme Carvalho <guilherme@spirl.com>
  • Loading branch information
guilhermocc authored Mar 5, 2024
1 parent 81de95e commit bef1690
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 23 deletions.
8 changes: 6 additions & 2 deletions pkg/agent/endpoints/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import (
secret_v3 "github.com/envoyproxy/go-control-plane/envoy/service/secret/v3"
"github.com/sirupsen/logrus"
workload_pb "github.com/spiffe/go-spiffe/v2/proto/spiffe/workload"
"google.golang.org/grpc"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"

healthv1 "github.com/spiffe/spire/pkg/agent/api/health/v1"
"github.com/spiffe/spire/pkg/agent/endpoints/sdsv3"
"github.com/spiffe/spire/pkg/agent/endpoints/workload"
"github.com/spiffe/spire/pkg/common/api/middleware"
"github.com/spiffe/spire/pkg/common/peertracker"
"github.com/spiffe/spire/pkg/common/telemetry"
"google.golang.org/grpc"
"google.golang.org/grpc/health/grpc_health_v1"
)

type Server interface {
Expand Down Expand Up @@ -106,6 +108,8 @@ func (e *Endpoints) ListenAndServe(ctx context.Context) error {
secret_v3.RegisterSecretDiscoveryServiceServer(server, e.sdsv3Server)
grpc_health_v1.RegisterHealthServer(server, e.healthServer)

reflection.Register(server)

l, err := e.createListener()
if err != nil {
return err
Expand Down
50 changes: 43 additions & 7 deletions pkg/agent/endpoints/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,25 @@ import (
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
workload_pb "github.com/spiffe/go-spiffe/v2/proto/spiffe/workload"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/reflection/grpc_reflection_v1"
"google.golang.org/grpc/status"

healthv1 "github.com/spiffe/spire/pkg/agent/api/health/v1"
"github.com/spiffe/spire/pkg/agent/api/rpccontext"
"github.com/spiffe/spire/pkg/agent/endpoints/sdsv3"
"github.com/spiffe/spire/pkg/agent/endpoints/workload"
"github.com/spiffe/spire/pkg/agent/manager"
"github.com/spiffe/spire/pkg/common/api/middleware"
"github.com/spiffe/spire/pkg/common/telemetry"
"github.com/spiffe/spire/pkg/common/util"
"github.com/spiffe/spire/test/fakes/fakemetrics"
"github.com/spiffe/spire/test/spiretest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)

func TestEndpoints(t *testing.T) {
Expand Down Expand Up @@ -126,6 +129,39 @@ func TestEndpoints(t *testing.T) {
name: "access denied to remote caller",
fromRemote: true,
},
{
name: "reflection enabled",
do: func(t *testing.T, conn *grpc.ClientConn) {
exposedServices := []string{
middleware.WorkloadAPIServiceName,
middleware.EnvoySDSv3ServiceName,
middleware.HealthServiceName,
middleware.ServerReflectionServiceName,
middleware.ServerReflectionV1AlphaServiceName,
}
client := grpc_reflection_v1.NewServerReflectionClient(conn)

clientStream, err := client.ServerReflectionInfo(ctx)
require.NoError(t, err)

err = clientStream.Send(&grpc_reflection_v1.ServerReflectionRequest{
MessageRequest: &grpc_reflection_v1.ServerReflectionRequest_ListServices{},
})
require.NoError(t, err)

resp, err := clientStream.Recv()
require.NoError(t, err)

listResp := resp.GetListServicesResponse()
require.NotNil(t, listResp)

var serviceNames []string
for _, service := range listResp.Service {
serviceNames = append(serviceNames, service.Name)
}
assert.ElementsMatch(t, exposedServices, serviceNames)
},
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
Expand Down
8 changes: 4 additions & 4 deletions pkg/agent/endpoints/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func (m *connectionMetrics) Preprocess(ctx context.Context, _ string, _ any) (co
case middleware.DelegatedIdentityServiceName:
adminapi.IncrDelegatedIdentityAPIConnectionCounter(m.metrics)
adminapi.SetDelegatedIdentityAPIConnectionGauge(m.metrics, atomic.AddInt32(&m.delegatedIdentityAPIConns, 1))
case middleware.HealthServiceName:
// Intentionally not emitting metrics for health
case middleware.HealthServiceName, middleware.ServerReflectionServiceName, middleware.ServerReflectionV1AlphaServiceName:
// Intentionally not emitting metrics for health and reflection services
default:
middleware.LogMisconfiguration(ctx, "unrecognized service for connection metrics: "+names.Service)
}
Expand All @@ -55,8 +55,8 @@ func (m *connectionMetrics) Postprocess(ctx context.Context, _ string, _ bool, _
sdsAPITelemetry.SetSDSAPIConnectionTotalGauge(m.metrics, atomic.AddInt32(&m.sdsAPIConns, -1))
case middleware.DelegatedIdentityServiceName:
adminapi.SetDelegatedIdentityAPIConnectionGauge(m.metrics, atomic.AddInt32(&m.delegatedIdentityAPIConns, -1))
case middleware.HealthServiceName:
// Intentionally not emitting metrics for health
case middleware.HealthServiceName, middleware.ServerReflectionServiceName, middleware.ServerReflectionV1AlphaServiceName:
// Intentionally not emitting metrics for health and reflection services
default:
middleware.LogMisconfiguration(ctx, "unrecognized service for connection metrics: "+names.Service)
}
Expand Down
22 changes: 12 additions & 10 deletions pkg/common/api/middleware/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ import (
const (
serverAPIPrefix = "spire.api.server."

WorkloadAPIServiceName = "SpiffeWorkloadAPI"
WorkloadAPIServiceShortName = "WorkloadAPI"
EnvoySDSv3ServiceName = "envoy.service.secret.v3.SecretDiscoveryService"
EnvoySDSv3ServiceShortName = "SDS.v3"
HealthServiceName = "grpc.health.v1.Health"
HealthServiceShortName = "Health"
DelegatedIdentityServiceName = "spire.api.agent.delegatedidentity.v1.DelegatedIdentity"
DelegatedIdentityServiceShortName = "DelegatedIdentity"
SubscribeToX509SVIDsMethodName = "SubscribeToX509SVIDs"
SubscribeToX509SVIDsMetricKey = "subscribe_to_x509_svids"
WorkloadAPIServiceName = "SpiffeWorkloadAPI"
WorkloadAPIServiceShortName = "WorkloadAPI"
EnvoySDSv3ServiceName = "envoy.service.secret.v3.SecretDiscoveryService"
EnvoySDSv3ServiceShortName = "SDS.v3"
HealthServiceName = "grpc.health.v1.Health"
HealthServiceShortName = "Health"
DelegatedIdentityServiceName = "spire.api.agent.delegatedidentity.v1.DelegatedIdentity"
DelegatedIdentityServiceShortName = "DelegatedIdentity"
ServerReflectionServiceName = "grpc.reflection.v1.ServerReflection"
ServerReflectionV1AlphaServiceName = "grpc.reflection.v1alpha.ServerReflection"
SubscribeToX509SVIDsMethodName = "SubscribeToX509SVIDs"
SubscribeToX509SVIDsMetricKey = "subscribe_to_x509_svids"
)

var (
Expand Down

0 comments on commit bef1690

Please sign in to comment.