2022-06-07 14:26:33 -04:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-02-02 17:15:17 -08:00
|
|
|
|
2022-05-24 14:10:13 -04:00
|
|
|
package handlers
|
2022-04-27 16:25:05 -04:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2022-06-01 13:35:46 -04:00
|
|
|
"errors"
|
2022-04-27 16:25:05 -04:00
|
|
|
"fmt"
|
2022-06-01 13:35:46 -04:00
|
|
|
"sync/atomic"
|
2022-04-27 16:25:05 -04:00
|
|
|
|
2022-06-01 13:35:46 -04:00
|
|
|
"github.com/hashicorp/nodeenrollment"
|
|
|
|
|
"github.com/hashicorp/nodeenrollment/multihop"
|
2022-05-19 14:17:01 -04:00
|
|
|
"github.com/hashicorp/nodeenrollment/registration"
|
2022-06-07 14:26:33 -04:00
|
|
|
"github.com/hashicorp/nodeenrollment/rotation"
|
2022-05-19 14:17:01 -04:00
|
|
|
"github.com/hashicorp/nodeenrollment/tls"
|
2022-05-16 09:02:09 -04:00
|
|
|
"github.com/hashicorp/nodeenrollment/types"
|
2022-06-01 13:35:46 -04:00
|
|
|
"github.com/hashicorp/nodeenrollment/util/temperror"
|
2022-04-27 16:25:05 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type multihopServiceServer struct {
|
2022-08-30 14:22:10 -04:00
|
|
|
multihop.UnsafeMultihopServiceServer
|
2022-04-27 16:25:05 -04:00
|
|
|
|
2022-06-01 13:35:46 -04:00
|
|
|
storage nodeenrollment.Storage
|
|
|
|
|
direct bool
|
|
|
|
|
client *atomic.Value
|
|
|
|
|
options []nodeenrollment.Option
|
2022-04-27 16:25:05 -04:00
|
|
|
}
|
|
|
|
|
|
2022-08-30 14:22:10 -04:00
|
|
|
var _ multihop.MultihopServiceServer = (*multihopServiceServer)(nil)
|
|
|
|
|
|
2022-06-07 14:26:33 -04:00
|
|
|
// NewMultihopServiceServer creates a new service implementing
|
|
|
|
|
// MultihopServiceServer, storing values used for the implementing functions.
|
2022-06-01 13:35:46 -04:00
|
|
|
func NewMultihopServiceServer(storage nodeenrollment.Storage, direct bool, client *atomic.Value, opt ...nodeenrollment.Option) (*multihopServiceServer, error) {
|
|
|
|
|
const op = "cluster.handlers.NewMultihopServiceServer"
|
|
|
|
|
|
|
|
|
|
switch {
|
|
|
|
|
case direct && nodeenrollment.IsNil(storage):
|
|
|
|
|
return nil, fmt.Errorf("%s: running on controller and nil storage provided", op)
|
|
|
|
|
case !direct && client == nil:
|
|
|
|
|
return nil, fmt.Errorf("%s: running on worker and nil client provided", op)
|
2022-04-27 16:25:05 -04:00
|
|
|
}
|
2022-06-01 13:35:46 -04:00
|
|
|
|
|
|
|
|
return &multihopServiceServer{
|
|
|
|
|
storage: storage,
|
|
|
|
|
direct: direct,
|
|
|
|
|
client: client,
|
|
|
|
|
options: opt,
|
|
|
|
|
}, nil
|
2022-04-27 16:25:05 -04:00
|
|
|
}
|
|
|
|
|
|
2022-06-07 14:26:33 -04:00
|
|
|
// FetchNodeCredentials implements the MultihopServiceServer interface. If it's
|
|
|
|
|
// direct (e.g. running on a controller) it handles the request directly,
|
|
|
|
|
// otherwise sends it to its next hop.
|
2022-05-16 09:02:09 -04:00
|
|
|
func (m *multihopServiceServer) FetchNodeCredentials(ctx context.Context, req *types.FetchNodeCredentialsRequest) (*types.FetchNodeCredentialsResponse, error) {
|
2022-06-01 13:35:46 -04:00
|
|
|
const op = "cluster.handlers.(multihopServiceServer).FetchNodeCredentials"
|
|
|
|
|
switch m.direct {
|
|
|
|
|
case true:
|
|
|
|
|
return registration.FetchNodeCredentials(ctx, m.storage, req, m.options...)
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
client := m.client.Load()
|
|
|
|
|
if client == nil {
|
|
|
|
|
return nil, fmt.Errorf("%s: error fetching multihop connection, client is nil", op)
|
|
|
|
|
}
|
|
|
|
|
multihopClient, ok := client.(multihop.MultihopServiceClient)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, temperror.New(errors.New("client could not be understood as a multihop service client"))
|
|
|
|
|
}
|
|
|
|
|
return multihopClient.FetchNodeCredentials(ctx, req)
|
2022-04-27 16:25:05 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-07 14:26:33 -04:00
|
|
|
// GenerateServerCertificates implements the MultihopServiceServer interface. If
|
|
|
|
|
// it's direct (e.g. running on a controller) it handles the request directly,
|
|
|
|
|
// otherwise sends it to its next hop.
|
2022-05-16 09:02:09 -04:00
|
|
|
func (m *multihopServiceServer) GenerateServerCertificates(ctx context.Context, req *types.GenerateServerCertificatesRequest) (*types.GenerateServerCertificatesResponse, error) {
|
2022-06-01 13:35:46 -04:00
|
|
|
const op = "cluster.handlers.(multihopServiceServer).GenerateServerCertificates"
|
|
|
|
|
switch m.direct {
|
|
|
|
|
case true:
|
|
|
|
|
return tls.GenerateServerCertificates(ctx, m.storage, req, m.options...)
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
client := m.client.Load()
|
|
|
|
|
if client == nil {
|
|
|
|
|
return nil, fmt.Errorf("%s: error fetching multihop connection, client is nil", op)
|
|
|
|
|
}
|
|
|
|
|
multihopClient, ok := client.(multihop.MultihopServiceClient)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, temperror.New(errors.New("client could not be understood as a multihop service client"))
|
|
|
|
|
}
|
|
|
|
|
return multihopClient.GenerateServerCertificates(ctx, req)
|
2022-04-27 16:25:05 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-07 14:26:33 -04:00
|
|
|
|
|
|
|
|
// RotateNodeCredentials implements the MultihopServiceServer interface. If it's
|
|
|
|
|
// direct (e.g. running on a controller) it handles the request directly,
|
|
|
|
|
// otherwise sends it to its next hop.
|
|
|
|
|
func (m *multihopServiceServer) RotateNodeCredentials(ctx context.Context, req *types.RotateNodeCredentialsRequest) (*types.RotateNodeCredentialsResponse, error) {
|
|
|
|
|
const op = "cluster.handlers.(multihopServiceServer).RotateNodeCredentials"
|
|
|
|
|
switch m.direct {
|
|
|
|
|
case true:
|
|
|
|
|
return rotation.RotateNodeCredentials(ctx, m.storage, req, m.options...)
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
client := m.client.Load()
|
|
|
|
|
if client == nil {
|
|
|
|
|
return nil, fmt.Errorf("%s: error fetching multihop connection, client is nil", op)
|
|
|
|
|
}
|
|
|
|
|
multihopClient, ok := client.(multihop.MultihopServiceClient)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, temperror.New(errors.New("client could not be understood as a multihop service client"))
|
|
|
|
|
}
|
|
|
|
|
return multihopClient.RotateNodeCredentials(ctx, req)
|
|
|
|
|
}
|
|
|
|
|
}
|