diff --git a/agent/cache-types/trust_bundles.go b/agent/cache-types/trust_bundles.go index 70c63cb4be6..bf8e55da193 100644 --- a/agent/cache-types/trust_bundles.go +++ b/agent/cache-types/trust_bundles.go @@ -8,6 +8,8 @@ import ( "github.com/mitchellh/hashstructure" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "github.com/hashicorp/consul/agent/cache" external "github.com/hashicorp/consul/agent/grpc-external" @@ -87,11 +89,18 @@ func (t *TrustBundles) Fetch(_ cache.FetchOptions, req cache.Request) (cache.Fet // Fetch reply, err := t.Client.TrustBundleListByService(external.ContextWithToken(context.Background(), reqReal.Token), reqReal.Request) if err != nil { - return result, err + grpcErr, ok := grpcstatus.FromError(err) + if !ok || grpcErr.Code() != codes.FailedPrecondition { + return result, err + } + + // handle the FailedPrecondition error and synthesize a fake result + result.Value = &pbpeering.TrustBundleListByServiceResponse{} + result.Index = 1 + } else { + result.Value = reply + result.Index = reply.Index } - result.Value = reply - result.Index = reply.Index - return result, nil } diff --git a/agent/cache-types/trust_bundles_test.go b/agent/cache-types/trust_bundles_test.go index 09d8a80bcb3..85248dba1da 100644 --- a/agent/cache-types/trust_bundles_test.go +++ b/agent/cache-types/trust_bundles_test.go @@ -7,6 +7,8 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/proto/pbpeering" @@ -48,6 +50,29 @@ func TestTrustBundles(t *testing.T) { }, result) } +func TestTrustBundles_PeeringDisabled(t *testing.T) { + client := NewMockTrustBundleLister(t) + typ := &TrustBundles{Client: client} + + var resp *pbpeering.TrustBundleListByServiceResponse + + // Expect the proper call. + // This also returns the canned response above. + client.On("TrustBundleListByService", mock.Anything, mock.Anything). + Return(resp, grpcstatus.Error(codes.FailedPrecondition, "peering must be enabled to use this endpoint")) + + // Fetch and assert against the result. + result, err := typ.Fetch(cache.FetchOptions{}, &TrustBundleListRequest{ + Request: &pbpeering.TrustBundleListByServiceRequest{ + ServiceName: "foo", + }, + }) + require.NoError(t, err) + require.NotNil(t, result) + require.EqualValues(t, 1, result.Index) + require.NotNil(t, result.Value) +} + func TestTrustBundles_badReqType(t *testing.T) { client := pbpeering.NewPeeringServiceClient(nil) typ := &TrustBundles{Client: client}