Skip to content

Commit

Permalink
Add the decisionv1.Service boilerplate (#49912)
Browse files Browse the repository at this point in the history
* Add the decisionv1.Service boilerplate

* Wire decisionv1.Service to auth.GRPCServer

* Wire decisionpb.DecisionServiceClient to client.Client

* Add basic service testing
  • Loading branch information
codingllama authored Dec 17, 2024
1 parent 988a531 commit 0aaca3f
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 0 deletions.
7 changes: 7 additions & 0 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import (
crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1"
dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1"
dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1"
decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1"
discoveryconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1"
dynamicwindowsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dynamicwindows/v1"
Expand Down Expand Up @@ -5217,3 +5218,9 @@ func (c *Client) ProvisioningServiceClient() provisioningv1.ProvisioningServiceC
func (c *Client) IntegrationsClient() integrationpb.IntegrationServiceClient {
return c.integrationsClient()
}

// DecisionClient returns an unadorned DecisionService client using the
// underlying Auth gRPC connection.
func (c *Client) DecisionClient() decisionpb.DecisionServiceClient {
return decisionpb.NewDecisionServiceClient(c.conn)
}
10 changes: 10 additions & 0 deletions lib/auth/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
crownjewelv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1"
dbobjectv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1"
dbobjectimportrulev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1"
decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
discoveryconfigv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1"
dynamicwindowsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dynamicwindows/v1"
gitserverv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/gitserver/v1"
Expand Down Expand Up @@ -109,6 +110,7 @@ import (
"github.com/gravitational/teleport/lib/auth/vnetconfig/vnetconfigv1"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/decision/decisionv1"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/httplib"
Expand Down Expand Up @@ -5466,6 +5468,14 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
loginrulev1pb.RegisterLoginRuleServiceServer(server, loginrulev1.NotImplementedService{})
}

decisionService, err := decisionv1.NewService(decisionv1.ServiceConfig{
Authorizer: cfg.Authorizer,
})
if err != nil {
return nil, trace.Wrap(err)
}
decisionpb.RegisterDecisionServiceServer(server, decisionService)

return authServer, nil
}

Expand Down
48 changes: 48 additions & 0 deletions lib/decision/decisionv1/decision_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Teleport
// Copyright (C) 2024 Gravitational, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package decisionv1

import (
"github.com/gravitational/trace"

decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
"github.com/gravitational/teleport/lib/authz"
)

// ServiceConfig holds creation parameters for [Service].
type ServiceConfig struct {
// Authorizer used by the service.
Authorizer authz.Authorizer
}

// Service implements the teleport.decision.v1alpha1.DecisionService gRPC API.
type Service struct {
decisionpb.UnimplementedDecisionServiceServer

authorizer authz.Authorizer
}

// NewService creates a new [Service] instance.
func NewService(cfg ServiceConfig) (*Service, error) {
if cfg.Authorizer == nil {
return nil, trace.BadParameter("param Authorizer required")
}

return &Service{
authorizer: cfg.Authorizer,
}, nil
}
45 changes: 45 additions & 0 deletions lib/decision/decisionv1/decision_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Teleport
// Copyright (C) 2024 Gravitational, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package decisionv1_test

import (
"context"
"testing"

"github.com/gravitational/trace"
"github.com/stretchr/testify/assert"

decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
)

func TestDecisionService_notImplemented(t *testing.T) {
t.Parallel()

env := NewTestenv(t)
decisionClient := env.DecisionClient
ctx := context.Background()

t.Run("EvaluateSSHAccess", func(t *testing.T) {
_, err := decisionClient.EvaluateSSHAccess(ctx, &decisionpb.EvaluateSSHAccessRequest{})
assert.ErrorAs(t, err, new(*trace.NotImplementedError), "EvaluateSSHAccess error mismatch")
})

t.Run("EvaluateDatabaseAccess", func(t *testing.T) {
_, err := decisionClient.EvaluateDatabaseAccess(ctx, &decisionpb.EvaluateDatabaseAccessRequest{})
assert.ErrorAs(t, err, new(*trace.NotImplementedError), "EvaluateDatabaseAccess error mismatch")
})
}
74 changes: 74 additions & 0 deletions lib/decision/decisionv1/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Teleport
// Copyright (C) 2024 Gravitational, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package decisionv1_test

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/constants"
decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/auth/authclient"
)

// Testenv is a test environment for decisionv1.Service.
type Testenv struct {
TestServer *auth.TestServer

// AuthAdminClient is an admin Auth client.
AuthAdminClient *authclient.Client

// DecisionClient is an admin decision client.
// Created from AuthAdminClient.
DecisionClient decisionpb.DecisionServiceClient
}

func NewTestenv(t *testing.T) *Testenv {
t.Helper()

testServer, err := auth.NewTestServer(auth.TestServerConfig{
Auth: auth.TestAuthServerConfig{
Dir: t.TempDir(),
AuthPreferenceSpec: &types.AuthPreferenceSpecV2{
SecondFactor: constants.SecondFactorOTP, // Required.
},
},
})
require.NoError(t, err, "NewTestServer failed")
t.Cleanup(func() {
assert.NoError(t,
testServer.Shutdown(context.Background()),
"testServer.Shutdown failed")
})

adminClient, err := testServer.NewClient(auth.TestAdmin())
require.NoError(t, err, "NewClient failed")
t.Cleanup(func() {
assert.NoError(t, adminClient.Close(), "adminClient.Close() failed")
})

return &Testenv{
TestServer: testServer,
AuthAdminClient: adminClient,
DecisionClient: adminClient.DecisionClient(),
}
}

0 comments on commit 0aaca3f

Please sign in to comment.