Skip to content

Commit

Permalink
Convert RegisterUsingToken RPC from HTTP to gRPC (#47853)
Browse files Browse the repository at this point in the history
* Add proto changews for shifting RegisterUsingToken to gRPC

* Implement RegisterUsingToken RPC and client fallback

* Add methods to `api/client`

* Adjust join/register code to try new API first and fallback to old

* Rejig JoinServerGRPCServer to invoke auth.Server

* Tidy up some code duplication

* Fix broken build

* Fix TestRegisterBot_RemoteAddr

* Fix TestServer_RegisterUsingTPMMethod

* Add test for new RegisterUsingToken gRPC RPC

* Remove unused helper function

* Fix test

* Walk back switch to gRPC endpoint for registration via proxy

* Remove unused code
  • Loading branch information
strideynet authored Oct 24, 2024
1 parent 1396179 commit bad3497
Show file tree
Hide file tree
Showing 18 changed files with 310 additions and 156 deletions.
11 changes: 11 additions & 0 deletions api/client/joinservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/gravitational/trace"

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
)

// JoinServiceClient is a client for the JoinService, which runs on both the
Expand Down Expand Up @@ -200,3 +201,13 @@ func (c *JoinServiceClient) RegisterUsingTPMMethod(

return certs, nil
}

// RegisterUsingToken registers the caller using a token and returns signed
// certs.
// This is used where a more specific RPC has not been introduced for the join
// method.
func (c *JoinServiceClient) RegisterUsingToken(
ctx context.Context, req *types.RegisterUsingTokenRequest,
) (*proto.Certs, error) {
return c.grpcClient.RegisterUsingToken(ctx, req)
}
144 changes: 93 additions & 51 deletions api/client/proto/joinservice.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions api/proto/teleport/legacy/client/proto/joinservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,7 @@ service JoinService {
// RegisterUsingTPMMethod allows registration of a new agent or Bot to the
// cluster using a known TPM.
rpc RegisterUsingTPMMethod(stream RegisterUsingTPMMethodRequest) returns (stream RegisterUsingTPMMethodResponse);
// RegisterUsingToken is used to register a new node to the cluster using one
// of the legacy join methods which do not yet have their own gRPC method.
rpc RegisterUsingToken(types.RegisterUsingTokenRequest) returns (Certs);
}
2 changes: 2 additions & 0 deletions lib/auth/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) {
srv.POST("/:version/trustedclusters/validate", srv.WithAuth(srv.validateTrustedCluster))

// Tokens
// TODO(strideynet): REMOVE IN 18.0.0 - this method is now gRPC
srv.POST("/:version/tokens/register", srv.WithAuth(srv.registerUsingToken))

// Namespaces
Expand Down Expand Up @@ -489,6 +490,7 @@ func rawMessage(data []byte, err error) (interface{}, error) {
return &m, nil
}

// TODO(strideynet): REMOVE IN v18.0.0
func (s *APIServer) registerUsingToken(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, _ httprouter.Params, version string) (interface{}, error) {
var req types.RegisterUsingTokenRequest
if err := httplib.ReadJSON(r, &req); err != nil {
Expand Down
47 changes: 5 additions & 42 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,11 @@ func (a *ServerWithRoles) GetClusterCACert(
return a.authServer.GetClusterCACert(ctx)
}

// Deprecated: This method only exists to service the RegisterUsingToken HTTP
// RPC, which has been replaced by an RPC on the JoinServiceServer.
// JoinServiceServer directly invokes auth.Server and performs its own checks
// on metadata.
// TODO(strideynet): DELETE IN V18.0.0
func (a *ServerWithRoles) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) {
isProxy := a.hasBuiltinRole(types.RoleProxy)

Expand Down Expand Up @@ -615,48 +620,6 @@ func (a *ServerWithRoles) RegisterUsingToken(ctx context.Context, req *types.Reg
return a.authServer.RegisterUsingToken(ctx, req)
}

// RegisterUsingIAMMethod registers the caller using the IAM join method and
// returns signed certs to join the cluster.
//
// See (*Server).RegisterUsingIAMMethod for further documentation.
//
// This wrapper does not do any extra authz checks, as the register method has
// its own authz mechanism.
func (a *ServerWithRoles) RegisterUsingIAMMethod(ctx context.Context, challengeResponse client.RegisterIAMChallengeResponseFunc) (*proto.Certs, error) {
certs, err := a.authServer.RegisterUsingIAMMethod(ctx, challengeResponse)
return certs, trace.Wrap(err)
}

// RegisterUsingAzureMethod registers the caller using the Azure join method and
// returns signed certs to join the cluster.
//
// See (*Server).RegisterUsingAzureMethod for further documentation.
//
// This wrapper does not do any extra authz checks, as the register method has
// its own authz mechanism.
func (a *ServerWithRoles) RegisterUsingAzureMethod(ctx context.Context, challengeResponse client.RegisterAzureChallengeResponseFunc) (*proto.Certs, error) {
certs, err := a.authServer.RegisterUsingAzureMethod(ctx, challengeResponse)
return certs, trace.Wrap(err)
}

// RegisterUsingTPMMethod registers the caller using the TPM join method and
// returns signed certs to join the cluster.
//
// See (*Server).RegisterUsingTPMMethod for further documentation.
//
// This wrapper does not do any extra authz checks, as the register method has
// its own authz mechanism.
func (a *ServerWithRoles) RegisterUsingTPMMethod(
ctx context.Context,
initReq *proto.RegisterUsingTPMMethodInitialRequest,
solveChallenge client.RegisterTPMChallengeResponseFunc,
) (*proto.Certs, error) {
certs, err := a.authServer.registerUsingTPMMethod(
ctx, initReq, solveChallenge,
)
return certs, trace.Wrap(err)
}

// GenerateHostCerts generates new host certificates (signed
// by the host certificate authority) for a node.
func (a *ServerWithRoles) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequest) (*proto.Certs, error) {
Expand Down
20 changes: 0 additions & 20 deletions lib/auth/authclient/http_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/breaker"
"github.com/gravitational/teleport/api/client"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
apidefaults "github.com/gravitational/teleport/api/defaults"
tracehttp "github.com/gravitational/teleport/api/observability/tracing/http"
Expand Down Expand Up @@ -336,25 +335,6 @@ func (c *HTTPClient) ProcessKubeCSR(req KubeCSR) (*KubeCSRResponse, error) {
return &re, nil
}

// RegisterUsingToken calls the auth service API to register a new node using a registration token
// which was previously issued via CreateToken/UpsertToken.
func (c *HTTPClient) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) {
if err := req.CheckAndSetDefaults(); err != nil {
return nil, trace.Wrap(err)
}
out, err := c.PostJSON(ctx, c.Endpoint("tokens", "register"), req)
if err != nil {
return nil, trace.Wrap(err)
}

var certs proto.Certs
if err := json.Unmarshal(out.Bytes(), &certs); err != nil {
return nil, trace.Wrap(err)
}

return &certs, nil
}

type upsertTunnelConnectionRawReq struct {
TunnelConnection json.RawMessage `json:"tunnel_connection"`
}
Expand Down
Loading

0 comments on commit bad3497

Please sign in to comment.