Files
threshold/internal/daemon/cluster/connstate.go
T
Todd 1e89be1b1a Downstream worker connections are tracked by worker id (#2949)
When possible downstream workers will include their worker id information in
the connections they establish with the upstream using the nodeenrollment
library.  The tracking listener now tracks connections that are connected in
this same way instead of just connections of type *tls.Conn.
2023-02-10 15:27:42 -08:00

62 lines
2.1 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package cluster
import (
"context"
"net"
"github.com/fatih/structs"
"github.com/hashicorp/boundary/internal/errors"
"github.com/mitchellh/mapstructure"
"google.golang.org/protobuf/types/known/structpb"
)
// WorkerConnectionInfo contains information about a worker that gets attached
// to outgoing connections to an upstream worker or the controller through the
// state of a *protocol.Conn.
type WorkerConnectionInfo struct {
// The address that the dialing worker is dialing
UpstreamAddress string `mapstructure:"upstream_address,omitempty"`
// The worker id of the worker that is dialing
WorkerId string `mapstructure:"worker_id,omitempty"`
// The version of the worker that is dialing
BoundaryVersion string `mapstructure:"boundary_version,omitempty"`
}
// AsConnectionStateStruct builds a structPb in the format that is expected for
// workers to attach their state to a *protocol.Conn through the withState option.
func (w *WorkerConnectionInfo) AsConnectionStateStruct() (*structpb.Struct, error) {
if w == nil {
return nil, nil
}
s := structs.New(w)
s.TagName = "mapstructure"
return structpb.NewStruct(s.Map())
}
type stateProvider interface {
State() *structpb.Struct
}
// GetWorkerInfoFromStateMap returns the WorkerConnectionInfo for the provided
// connection if the connection is a stateProvider. If it is not a stateProvider
// or if the provided state is nil, an error is returned.
func GetWorkerInfoFromStateMap(ctx context.Context, c net.Conn) (*WorkerConnectionInfo, error) {
const op = "cluster.GetWorkerInfoFromStateMap"
var downstreamInfo WorkerConnectionInfo
pc, ok := c.(stateProvider)
if !ok {
return nil, errors.New(ctx, errors.InvalidParameter, op, "connection does not provide a State structpb.Struct")
}
st := pc.State()
if st == nil {
return nil, errors.New(ctx, errors.InvalidParameter, op, "no state attached to connection")
}
if err := mapstructure.Decode(st.AsMap(), &downstreamInfo); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
return &downstreamInfo, nil
}