Update to new nodee lib bits (#2120)
This commit is contained in:
1 parent
5aebd5689f
commit
46e97a2b91
13 files changed
+179
-135
No files matched your search
@@ -92,7 +92,7 @@ require github.com/hashicorp/go-dbw v0.0.0-20220412153211-c470aec9369f // this i
|
||||
require (
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220515130442-cac0b5ac133b
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220520141833-ad7323153acc
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220601055910-5718dde51fae
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -166,7 +166,6 @@ require (
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/runc v1.0.2 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
|
||||
@@ -740,8 +740,8 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220520141833-ad7323153acc h1:7RE6UxjVxa3uUS0A4RZwVRFnBJqNQnm5nzNwqPJy4VM=
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220520141833-ad7323153acc/go.mod h1:3054+zYuaQzgXjoy8kyd8whmx1dXUSomyMTRnWHzVXs=
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220601055910-5718dde51fae h1:A8JdiMkZuic8905EgiTDw9cKOb6v1BSrfDMNlS9oejo=
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220601055910-5718dde51fae/go.mod h1:8l3RSuZJAibZKnqX6tvLaeoFzPhDf4oCRVsyFjU5Soc=
|
||||
github.com/hashicorp/vault/api v1.3.1 h1:pkDkcgTh47PRjY1NEFeofqR4W/HkNUi9qIakESO2aRM=
|
||||
github.com/hashicorp/vault/api v1.3.1/go.mod h1:QeJoWxMFt+MsuWcYhmwRLwKEXrjwAFFywzhptMsTIUw=
|
||||
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||
@@ -1088,8 +1088,6 @@ github.com/ory/dockertest/v3 v3.7.0 h1:Bijzonc69Ont3OU0a3TWKJ1Rzlh3TsDXP1JrTAkSm
|
||||
github.com/ory/dockertest/v3 v3.7.0/go.mod h1:PvCCgnP7AfBZeVrzwiUTjZx/IUXlGLC1zQlUQrLIlUE=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||
"github.com/hashicorp/nodeenrollment"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
"go.uber.org/atomic"
|
||||
@@ -602,7 +601,7 @@ func (c *Command) Run(args []string) int {
|
||||
opts = append(opts, base.WithContainerImage(c.flagContainerImage))
|
||||
}
|
||||
if err := c.CreateDevDatabase(c.Context, opts...); err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error creating dev database container %w", err).Error())
|
||||
c.UI.Error(fmt.Errorf("Error creating dev database container: %w", err).Error())
|
||||
return base.CommandCliError
|
||||
}
|
||||
|
||||
@@ -677,23 +676,22 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
|
||||
if !c.flagUseEphemeralKmsWorkerAuthMethod {
|
||||
if c.worker.NodeeKeyId == "" {
|
||||
c.UI.Error("No worker key ID found at worker registration time")
|
||||
req := c.worker.NodeeRegistrationRequest
|
||||
if req == "" {
|
||||
c.UI.Error("No worker registration request found at worker start time")
|
||||
return base.CommandCliError
|
||||
}
|
||||
c.InfoKeys = append(c.InfoKeys, "worker key identifier")
|
||||
c.Info["worker key identifier"] = c.worker.NodeeKeyId
|
||||
c.InfoKeys = append(c.InfoKeys, "worker registration request")
|
||||
c.Info["worker registration request"] = req
|
||||
c.InfoKeys = append(c.InfoKeys, "worker current key id")
|
||||
c.Info["worker current key id"] = c.worker.NodeeCurrentKeyId
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-c.Context.Done():
|
||||
return
|
||||
case <-time.After(time.Second):
|
||||
waitingNodes := nodeenrollment.DefaultRegistrationCache.Items()
|
||||
if len(waitingNodes) == 0 {
|
||||
continue
|
||||
}
|
||||
if err := c.controller.AuthorizeNodeeWorker(c.worker.NodeeKeyId); err != nil {
|
||||
if err := c.controller.AuthorizeNodeeWorker(req); err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error authorizing node: %w", err).Error())
|
||||
errorEncountered.Store(true)
|
||||
return
|
||||
|
||||
@@ -464,8 +464,9 @@ func (c *Command) Run(args []string) int {
|
||||
return base.CommandCliError
|
||||
}
|
||||
if c.WorkerAuthKms == nil {
|
||||
if c.worker.NodeeKeyId == "" {
|
||||
retErr := fmt.Errorf("No worker key ID found at worker registration time")
|
||||
req := c.worker.NodeeRegistrationRequest
|
||||
if req == "" {
|
||||
retErr := fmt.Errorf("No worker registration request found at worker startup time")
|
||||
if err := c.worker.Shutdown(); err != nil {
|
||||
c.UI.Error(retErr.Error())
|
||||
retErr = fmt.Errorf("Error shutting down worker: %w", err)
|
||||
@@ -476,8 +477,10 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
return base.CommandCliError
|
||||
}
|
||||
c.InfoKeys = append(c.InfoKeys, "worker key identifier")
|
||||
c.Info["worker key identifier"] = c.worker.NodeeKeyId
|
||||
c.InfoKeys = append(c.InfoKeys, "worker registration request")
|
||||
c.Info["worker registration request"] = req
|
||||
c.InfoKeys = append(c.InfoKeys, "worker current key id")
|
||||
c.Info["worker current key id"] = c.worker.NodeeCurrentKeyId
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,45 +2,81 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
pbs "github.com/hashicorp/nodeenrollment/multihop"
|
||||
"github.com/hashicorp/nodeenrollment/nodeauth"
|
||||
"github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/multihop"
|
||||
"github.com/hashicorp/nodeenrollment/registration"
|
||||
"github.com/hashicorp/nodeenrollment/tls"
|
||||
"github.com/hashicorp/nodeenrollment/types"
|
||||
"github.com/hashicorp/nodeenrollment/util/temperror"
|
||||
)
|
||||
|
||||
type multihopServiceServer struct {
|
||||
pbs.UnimplementedMultihopServiceServer
|
||||
multihop.UnimplementedMultihopServiceServer
|
||||
|
||||
currentParams nodeauth.CurrentParameterFactory
|
||||
storage nodeenrollment.Storage
|
||||
direct bool
|
||||
client *atomic.Value
|
||||
options []nodeenrollment.Option
|
||||
}
|
||||
|
||||
func NewMultihopServiceServer(
|
||||
currentParams nodeauth.CurrentParameterFactory,
|
||||
) *multihopServiceServer {
|
||||
return &multihopServiceServer{
|
||||
currentParams: currentParams,
|
||||
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)
|
||||
}
|
||||
|
||||
return &multihopServiceServer{
|
||||
storage: storage,
|
||||
direct: direct,
|
||||
client: client,
|
||||
options: opt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var _ pbs.MultihopServiceServer = (*multihopServiceServer)(nil)
|
||||
var _ multihop.MultihopServiceServer = (*multihopServiceServer)(nil)
|
||||
|
||||
func (m *multihopServiceServer) FetchNodeCredentials(ctx context.Context, req *types.FetchNodeCredentialsRequest) (*types.FetchNodeCredentialsResponse, error) {
|
||||
const op = "workers.(multihopServiceServer).FetchNodeCredentials"
|
||||
_, storage, opt, err := m.currentParams()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error getting current parameters: %w", op, err)
|
||||
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)
|
||||
}
|
||||
return registration.FetchNodeCredentials(ctx, storage, req, opt...)
|
||||
}
|
||||
|
||||
func (m *multihopServiceServer) GenerateServerCertificates(ctx context.Context, req *types.GenerateServerCertificatesRequest) (*types.GenerateServerCertificatesResponse, error) {
|
||||
const op = "workers.(multihopServiceServer).GenerateServerCertificates"
|
||||
_, storage, opt, err := m.currentParams()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error getting current parameters: %w", op, err)
|
||||
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)
|
||||
}
|
||||
return tls.GenerateServerCertificates(ctx, storage, req, opt...)
|
||||
}
|
||||
@@ -39,8 +39,11 @@ import (
|
||||
"github.com/hashicorp/nodeenrollment/registration"
|
||||
"github.com/hashicorp/nodeenrollment/rotation"
|
||||
nodeefile "github.com/hashicorp/nodeenrollment/storage/file"
|
||||
"github.com/hashicorp/nodeenrollment/types"
|
||||
"github.com/mr-tron/base58"
|
||||
ua "go.uber.org/atomic"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
@@ -311,6 +314,7 @@ func (c *Controller) Start() error {
|
||||
event.WriteSysEvent(context.TODO(), op, "already started, skipping")
|
||||
return nil
|
||||
}
|
||||
|
||||
c.baseContext, c.baseCancel = context.WithCancel(context.Background())
|
||||
|
||||
var err error
|
||||
@@ -406,6 +410,16 @@ func (c *Controller) WorkerStatusUpdateTimes() *sync.Map {
|
||||
return c.workerStatusUpdateTimes
|
||||
}
|
||||
|
||||
func (c *Controller) AuthorizeNodeeWorker(keyId string) error {
|
||||
return registration.AuthorizeNode(c.baseContext, c.NodeeFileStorage, keyId)
|
||||
func (c *Controller) AuthorizeNodeeWorker(request string) error {
|
||||
const op = "controller.(Controller).AuthorizeWorker"
|
||||
reqBytes, err := base58.FastBase58Decoding(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("(%s) error base64-decoding fetch node creds next proto value", op)
|
||||
}
|
||||
// Decode the proto into the request
|
||||
req := new(types.FetchNodeCredentialsRequest)
|
||||
if err := proto.Unmarshal(reqBytes, req); err != nil {
|
||||
return fmt.Errorf("(%s) error unmarshaling common name value: %w", op, err)
|
||||
}
|
||||
return registration.AuthorizeNode(c.baseContext, c.NodeeFileStorage, req)
|
||||
}
|
||||
@@ -43,8 +43,6 @@ import (
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||
"github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/types"
|
||||
"github.com/mr-tron/base58"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -568,34 +566,6 @@ func wrapHandlerWithCallbackInterceptor(h http.Handler, c *Controller) http.Hand
|
||||
func handleNodes(c *Controller) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodGet:
|
||||
type vals struct {
|
||||
WaitingNodes []string `json:"waiting_nodes"`
|
||||
}
|
||||
var err error
|
||||
var currVals vals
|
||||
waitingNodes := nodeenrollment.DefaultRegistrationCache.Items()
|
||||
for keyId, val := range waitingNodes {
|
||||
ni := val.(*types.NodeInformation)
|
||||
if ni.Authorized {
|
||||
continue
|
||||
}
|
||||
currVals.WaitingNodes = append(currVals.WaitingNodes, keyId)
|
||||
}
|
||||
ret, err := json.Marshal(currVals)
|
||||
if err != nil {
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
_, err = w.Write(ret)
|
||||
if err != nil {
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(200)
|
||||
return
|
||||
|
||||
case http.MethodPost:
|
||||
body, err := io.ReadAll(req.Body)
|
||||
@@ -606,7 +576,7 @@ func handleNodes(c *Controller) http.Handler {
|
||||
return
|
||||
}
|
||||
type val struct {
|
||||
KeyId string `json:"key_id"`
|
||||
Request string `json:"request"`
|
||||
}
|
||||
var currVal val
|
||||
if err := json.Unmarshal(body, &currVal); err != nil {
|
||||
@@ -614,7 +584,7 @@ func handleNodes(c *Controller) http.Handler {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
if err := c.AuthorizeNodeeWorker(currVal.KeyId); err != nil {
|
||||
if err := c.AuthorizeNodeeWorker(currVal.Request); err != nil {
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/nodeauth"
|
||||
)
|
||||
|
||||
// tempError is an error that satisfies the temporary error interface that is
|
||||
@@ -79,7 +78,7 @@ func (m *interceptingListener) Accept() (net.Conn, error) {
|
||||
|
||||
tlsConn := conn.(*tls.Conn)
|
||||
switch {
|
||||
case nodeauth.ContainsNodeAuthAlpnProto(tlsConn.ConnectionState().NegotiatedProtocol):
|
||||
case nodee.ContainsKnownAlpnProto(tlsConn.ConnectionState().NegotiatedProtocol):
|
||||
keyId, err := nodee.KeyIdFromPkix(tlsConn.ConnectionState().PeerCertificates[0].SubjectKeyId)
|
||||
if err != nil {
|
||||
if err := conn.Close(); err != nil {
|
||||
|
||||
@@ -17,9 +17,8 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/internal/metric"
|
||||
pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/multihop"
|
||||
"github.com/hashicorp/nodeenrollment/nodeauth"
|
||||
"github.com/hashicorp/nodeenrollment/protocol"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@@ -106,18 +105,16 @@ func (c *Controller) configureForApi(ln *base.ServerListener) ([]func(), error)
|
||||
}
|
||||
|
||||
func (c *Controller) configureForCluster(ln *base.ServerListener) (func(), error) {
|
||||
l, err := nodeauth.NewInterceptingListener(
|
||||
ln.ClusterListener,
|
||||
&tls.Config{
|
||||
GetConfigForClient: c.validateWorkerTls,
|
||||
},
|
||||
nodeauth.MakeCurrentParametersFactory(
|
||||
c.baseContext,
|
||||
nodee.NopTransactionStorage(c.NodeeFileStorage),
|
||||
),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
const op = "controller.configureForCluster"
|
||||
l, err := protocol.NewInterceptingListener(
|
||||
&protocol.InterceptingListenerConfiguration{
|
||||
Context: c.baseContext,
|
||||
Storage: c.NodeeFileStorage,
|
||||
BaseListener: ln.ClusterListener,
|
||||
BaseTlsConfiguration: &tls.Config{
|
||||
GetConfigForClient: c.validateWorkerTls,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error instantiating node auth listener: %w", err)
|
||||
}
|
||||
@@ -145,9 +142,14 @@ func (c *Controller) configureForCluster(ln *base.ServerListener) (func(), error
|
||||
pbs.RegisterServerCoordinationServiceServer(workerServer, workerService)
|
||||
pbs.RegisterSessionServiceServer(workerServer, workerService)
|
||||
|
||||
multihopService := handlers.NewMultihopServiceServer(
|
||||
nodeauth.MakeCurrentParametersFactory(c.baseContext, nodee.NopTransactionStorage(c.NodeeFileStorage)),
|
||||
multihopService, err := handlers.NewMultihopServiceServer(
|
||||
c.NodeeFileStorage,
|
||||
true,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error creating multihop service handler: %w", op, err)
|
||||
}
|
||||
multihop.RegisterMultihopServiceServer(workerServer, multihopService)
|
||||
|
||||
metric.InitializeClusterCollectors(c.conf.PrometheusRegisterer, workerServer)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/hashicorp/go-secure-stdlib/base62"
|
||||
"github.com/hashicorp/go-secure-stdlib/configutil/v2"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
nodeefile "github.com/hashicorp/nodeenrollment/storage/file"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -250,6 +251,9 @@ func TestStartListeners(t *testing.T) {
|
||||
c.baseContext = ctx
|
||||
c.baseCancel = cancel
|
||||
|
||||
c.NodeeFileStorage, err = nodeefile.NewFileStorage(c.baseContext)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = c.startListeners()
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -23,9 +23,8 @@ import (
|
||||
pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
"github.com/hashicorp/go-secure-stdlib/base62"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/multihop"
|
||||
"github.com/hashicorp/nodeenrollment/nodeauth"
|
||||
"github.com/hashicorp/nodeenrollment/protocol"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/backoff"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
@@ -74,11 +73,7 @@ func (w *Worker) controllerDialerFunc() func(context.Context, string) (net.Conn,
|
||||
case w.conf.WorkerAuthKms != nil:
|
||||
conn, err = w.v1KmsAuthDialFn(ctx, addr)
|
||||
default:
|
||||
conn, err = nodeauth.AuthDialFn(
|
||||
nodeauth.MakeCurrentParametersFactory(
|
||||
ctx,
|
||||
nodee.NopTransactionStorage(w.NodeeFileStorage),
|
||||
))(ctx, addr)
|
||||
conn, err = protocol.Dial(ctx, w.NodeeFileStorage, addr)
|
||||
}
|
||||
|
||||
if !w.everAuthenticated.Load() && err == nil && conn != nil {
|
||||
|
||||
@@ -19,8 +19,10 @@ import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/multihop"
|
||||
"github.com/hashicorp/nodeenrollment/nodeauth"
|
||||
"github.com/hashicorp/nodeenrollment/protocol"
|
||||
"github.com/hashicorp/nodeenrollment/types"
|
||||
"github.com/hashicorp/nodeenrollment/util/splitlistener"
|
||||
"github.com/hashicorp/nodeenrollment/util/temperror"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@@ -50,6 +52,8 @@ func (w *Worker) startListeners() error {
|
||||
}
|
||||
|
||||
func (w *Worker) configureForWorker(ln *base.ServerListener, logger *log.Logger) (func(), error) {
|
||||
const op = "worker.configureForWorker"
|
||||
|
||||
handler, err := w.handler(HandlerProperties{ListenerConfig: ln.Config})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -88,12 +92,13 @@ func (w *Worker) configureForWorker(ln *base.ServerListener, logger *log.Logger)
|
||||
) (*types.FetchNodeCredentialsResponse, error) {
|
||||
client := w.controllerMultihopConn.Load()
|
||||
if client == nil {
|
||||
return nil, nodeauth.NewTempError(errors.New("error fetching controller connection, client is nil"))
|
||||
return nil, temperror.New(errors.New("error fetching controller connection, client is nil"))
|
||||
}
|
||||
multihopClient, ok := client.(multihop.MultihopServiceClient)
|
||||
if !ok {
|
||||
return nil, nodeauth.NewTempError(errors.New("client could not be understood as a multihop service client"))
|
||||
return nil, temperror.New(errors.New("client could not be understood as a multihop service client"))
|
||||
}
|
||||
// log.Println("proxying fetch node credentials request")
|
||||
return multihopClient.FetchNodeCredentials(ctx, req)
|
||||
}
|
||||
|
||||
@@ -105,40 +110,45 @@ func (w *Worker) configureForWorker(ln *base.ServerListener, logger *log.Logger)
|
||||
) (*types.GenerateServerCertificatesResponse, error) {
|
||||
client := w.controllerMultihopConn.Load()
|
||||
if client == nil {
|
||||
return nil, nodeauth.NewTempError(errors.New("error fetching controller connection, client is nil"))
|
||||
return nil, temperror.New(errors.New("error fetching controller connection, client is nil"))
|
||||
}
|
||||
multihopClient, ok := client.(multihop.MultihopServiceClient)
|
||||
if !ok {
|
||||
return nil, nodeauth.NewTempError(errors.New("client could not be understood as a multihop service client"))
|
||||
return nil, temperror.New(errors.New("client could not be understood as a multihop service client"))
|
||||
}
|
||||
// log.Println("proxying generate server cert request")
|
||||
return multihopClient.GenerateServerCertificates(ctx, req)
|
||||
}
|
||||
|
||||
interceptingListener, err := nodeauth.NewInterceptingListener(
|
||||
ln.ProxyListener,
|
||||
&tls.Config{
|
||||
GetConfigForClient: w.getSessionTls,
|
||||
},
|
||||
nodeauth.MakeCurrentParametersFactory(
|
||||
w.baseContext,
|
||||
nodee.NopTransactionStorage(w.NodeeFileStorage),
|
||||
),
|
||||
fetchCredsFn,
|
||||
generateServerCertificatesFn,
|
||||
)
|
||||
interceptingListener, err := protocol.NewInterceptingListener(
|
||||
&protocol.InterceptingListenerConfiguration{
|
||||
Context: w.baseContext,
|
||||
Storage: w.NodeeFileStorage,
|
||||
BaseListener: ln.ProxyListener,
|
||||
BaseTlsConfiguration: &tls.Config{
|
||||
GetConfigForClient: w.getSessionTls,
|
||||
},
|
||||
FetchCredsFunc: fetchCredsFn,
|
||||
GenerateServerCertificatesFunc: generateServerCertificatesFn,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error instantiating node auth listener: %w", err)
|
||||
}
|
||||
|
||||
w.nodeeTeeListener = nodeauth.NewTeeListener(interceptingListener)
|
||||
w.nodeeSplitListener = splitlistener.New(interceptingListener)
|
||||
|
||||
downstreamServer := grpc.NewServer(
|
||||
grpc.MaxRecvMsgSize(math.MaxInt32),
|
||||
grpc.MaxSendMsgSize(math.MaxInt32),
|
||||
)
|
||||
multihopService := handlers.NewMultihopServiceServer(
|
||||
nodeauth.MakeCurrentParametersFactory(w.baseContext, nodee.NopTransactionStorage(w.NodeeFileStorage)),
|
||||
multihopService, err := handlers.NewMultihopServiceServer(
|
||||
w.NodeeFileStorage,
|
||||
false,
|
||||
w.controllerMultihopConn,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error creating multihop service handler: %w", op, err)
|
||||
}
|
||||
multihop.RegisterMultihopServiceServer(downstreamServer, multihopService)
|
||||
statusSessionService := NewWorkerProxyServiceServer(w.controllerStatusConn, w.controllerSessionConn)
|
||||
pbs.RegisterServerCoordinationServiceServer(downstreamServer, statusSessionService)
|
||||
@@ -147,9 +157,9 @@ func (w *Worker) configureForWorker(ln *base.ServerListener, logger *log.Logger)
|
||||
ln.GrpcServer = downstreamServer
|
||||
|
||||
return func() {
|
||||
go w.nodeeTeeListener.Start()
|
||||
go httpServer.Serve(w.nodeeTeeListener.OtherListener())
|
||||
go ln.GrpcServer.Serve(w.nodeeTeeListener.NodeeListener())
|
||||
go w.nodeeSplitListener.Start()
|
||||
go httpServer.Serve(w.nodeeSplitListener.OtherListener())
|
||||
go ln.GrpcServer.Serve(w.nodeeSplitListener.NodeEnrollmentListener())
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -162,21 +172,21 @@ func (w *Worker) stopServersAndListeners() error {
|
||||
// really likes to hang on closing. Maybe because it's never served a
|
||||
// connection? This is a workaround to force it until I can dig in.
|
||||
var cancel context.CancelFunc
|
||||
if w.nodeeTeeListener != nil {
|
||||
if w.nodeeSplitListener != nil {
|
||||
var ctx context.Context
|
||||
ctx, cancel = context.WithTimeout(w.baseContext, 2*time.Second)
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
w.nodeeTeeListener.Stop()
|
||||
w.nodeeSplitListener.Stop()
|
||||
cancel()
|
||||
}()
|
||||
}
|
||||
|
||||
stopErrors := mg.Wait()
|
||||
|
||||
if w.nodeeTeeListener != nil {
|
||||
if w.nodeeSplitListener != nil {
|
||||
cancel()
|
||||
err := w.nodeeTeeListener.Stop()
|
||||
err := w.nodeeSplitListener.Stop()
|
||||
if err != nil {
|
||||
stopErrors = multierror.Append(stopErrors, err)
|
||||
}
|
||||
@@ -227,8 +237,8 @@ func (w *Worker) stopAnyListeners() error {
|
||||
}
|
||||
var closeErrors *multierror.Error
|
||||
var err error
|
||||
if w.nodeeTeeListener != nil {
|
||||
err = w.nodeeTeeListener.Stop()
|
||||
if w.nodeeSplitListener != nil {
|
||||
err = w.nodeeSplitListener.Stop()
|
||||
} else if w.proxyListener.ProxyListener != nil {
|
||||
err = w.proxyListener.ProxyListener.Close()
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/servers"
|
||||
"github.com/hashicorp/nodeenrollment"
|
||||
"github.com/mr-tron/base58"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
@@ -26,13 +28,13 @@ import (
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-secure-stdlib/base62"
|
||||
"github.com/hashicorp/go-secure-stdlib/mlock"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/nodeauth"
|
||||
nodeefile "github.com/hashicorp/nodeenrollment/storage/file"
|
||||
"github.com/hashicorp/nodeenrollment/types"
|
||||
"github.com/hashicorp/nodeenrollment/util/splitlistener"
|
||||
ua "go.uber.org/atomic"
|
||||
"google.golang.org/grpc/resolver"
|
||||
"google.golang.org/grpc/resolver/manual"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type randFn func(length int) (string, error)
|
||||
@@ -73,9 +75,10 @@ type Worker struct {
|
||||
updateTags *ua.Bool
|
||||
|
||||
// PoC: Testing bits for BYOW
|
||||
NodeeFileStorage *nodeefile.FileStorage
|
||||
NodeeKeyId string
|
||||
nodeeTeeListener *nodeauth.TeeListener
|
||||
NodeeFileStorage *nodeefile.FileStorage
|
||||
NodeeCurrentKeyId string
|
||||
NodeeRegistrationRequest string
|
||||
nodeeSplitListener *splitlistener.SplitListener
|
||||
|
||||
// Test-specific options
|
||||
TestOverrideX509VerifyDnsName string
|
||||
@@ -190,7 +193,20 @@ func (w *Worker) Start() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error generating new node creds: %w", err)
|
||||
}
|
||||
w.NodeeKeyId, err = nodee.KeyIdFromPkix(nodeCreds.CertificatePublicKeyPkix)
|
||||
|
||||
req, err := nodeCreds.CreateFetchNodeCredentialsRequest(w.baseContext)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating fetch credentials request: %w", err)
|
||||
}
|
||||
reqBytes, err := proto.Marshal(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshaling fetch credentials request: %w", err)
|
||||
}
|
||||
w.NodeeRegistrationRequest = base58.FastBase58Encoding(reqBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error encoding registration request: %w", err)
|
||||
}
|
||||
w.NodeeCurrentKeyId, err = nodeenrollment.KeyIdFromPkix(nodeCreds.CertificatePublicKeyPkix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deriving key id: %w", err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user