1 parent
4819d17ee8
commit
b2bab45c13
20 files changed
+145
-105
No files matched your search
@@ -36,17 +36,13 @@ golangci-lint:
|
||||
$(eval GOLINT_INSTALLED := $(shell which golangci-lint))
|
||||
|
||||
if [ "$(GOLINT_INSTALLED)" = "" ]; then \
|
||||
sh scripts/install-golangci-lint.sh -b $(GO_PATH)/bin v1.51.0; \
|
||||
sh scripts/install-golangci-lint.sh -b $(GO_PATH)/bin v1.51.2; \
|
||||
fi;
|
||||
|
||||
.PHONY: cleangen
|
||||
cleangen:
|
||||
@rm -f $(shell find ${THIS_DIR} -name '*.gen.go' && find ${THIS_DIR} -name '*.pb.go' && find ${THIS_DIR} -name '*.pb.gw.go')
|
||||
|
||||
.PHONY: install-no-plugins
|
||||
install-no-plugins: export SKIP_PLUGIN_BUILD=1
|
||||
install-no-plugins: install
|
||||
|
||||
.PHONY: dev
|
||||
dev:
|
||||
@echo "This command has changed. Please use:"
|
||||
@@ -65,6 +61,10 @@ build: build-ui-ifne
|
||||
install: export BOUNDARY_INSTALL_BINARY=1
|
||||
install: build
|
||||
|
||||
.PHONY: install-no-plugins
|
||||
install-no-plugins: export SKIP_PLUGIN_BUILD=1
|
||||
install-no-plugins: install
|
||||
|
||||
.PHONY: build-memprof
|
||||
build-memprof: BUILD_TAGS+=memprofiler
|
||||
build-memprof:
|
||||
@@ -283,7 +283,7 @@ generate-database-dumps:
|
||||
test-ci: export CI_BUILD=1
|
||||
test-ci:
|
||||
CGO_ENABLED=$(CGO_ENABLED) BUILD_TAGS='$(BUILD_TAGS)' sh -c "'$(CURDIR)/scripts/build.sh'"
|
||||
go test "$(TEST_PACKAGE)" -v $(TESTARGS) -json -cover -timeout 120m | tparse -follow
|
||||
go test "$(TEST_PACKAGE)" -tags="$(BUILD_TAGS)" -v $(TESTARGS) -json -cover -timeout 120m | tparse -follow
|
||||
|
||||
.PHONY: test-sql
|
||||
test-sql:
|
||||
@@ -291,7 +291,7 @@ test-sql:
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test "$(TEST_PACKAGE)" $(TESTARGS) -json -cover -timeout $(TEST_TIMEOUT) | tparse -follow
|
||||
go test "$(TEST_PACKAGE)" -tags="$(BUILD_TAGS)" $(TESTARGS) -json -cover -timeout $(TEST_TIMEOUT) | tparse -follow
|
||||
|
||||
.PHONY: test-sdk
|
||||
test-sdk:
|
||||
|
||||
@@ -40,6 +40,7 @@ type WorkerAuthInfo struct {
|
||||
Description string `json:"description"`
|
||||
ConnectionNonce string `json:"connection_nonce"`
|
||||
ProxyAddress string `json:"proxy_address"`
|
||||
BoundaryVersion string `json:"boundary_version"`
|
||||
}
|
||||
|
||||
// Factory is the factory function to create a listener.
|
||||
|
||||
@@ -48,6 +48,8 @@ var (
|
||||
_ cli.CommandAutocomplete = (*Command)(nil)
|
||||
)
|
||||
|
||||
var extraSelfTerminationConditionFuncs []func(context.Context, chan struct{})
|
||||
|
||||
type Command struct {
|
||||
*base.Server
|
||||
opsServer *ops.Server
|
||||
@@ -921,6 +923,10 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range extraSelfTerminationConditionFuncs {
|
||||
f(c.Context, c.ServerSideShutdownCh)
|
||||
}
|
||||
|
||||
for !errorEncountered.Load() && !shutdownCompleted.Load() {
|
||||
select {
|
||||
case <-c.ServerSideShutdownCh:
|
||||
|
||||
@@ -41,6 +41,8 @@ var (
|
||||
_ cli.CommandAutocomplete = (*Command)(nil)
|
||||
)
|
||||
|
||||
var extraSelfTerminationConditionFuncs []func(context.Context, chan struct{})
|
||||
|
||||
type Command struct {
|
||||
*base.Server
|
||||
opsServer *ops.Server
|
||||
@@ -697,6 +699,10 @@ func (c *Command) WaitForInterrupt() int {
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range extraSelfTerminationConditionFuncs {
|
||||
f(c.Context, c.ServerSideShutdownCh)
|
||||
}
|
||||
|
||||
for !shutdownCompleted.Load() {
|
||||
select {
|
||||
case <-c.ServerSideShutdownCh:
|
||||
|
||||
@@ -73,6 +73,9 @@ func (c *Command) Run(args []string) int {
|
||||
if verInfo.VersionMetadata != "" {
|
||||
nonAttributeMap["Metadata"] = verInfo.VersionMetadata
|
||||
}
|
||||
if verInfo.BuildDate != "" {
|
||||
nonAttributeMap["Build Date"] = verInfo.BuildDate
|
||||
}
|
||||
|
||||
maxLength := base.MaxAttributesLength(nonAttributeMap, nil, nil)
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
var extraParsingFuncs []func(*Config) error
|
||||
|
||||
const (
|
||||
desktopCorsOrigin = "serve://boundary"
|
||||
|
||||
@@ -188,6 +190,9 @@ type Controller struct {
|
||||
//
|
||||
// TODO: This field is currently internal.
|
||||
SchedulerRunJobInterval time.Duration `hcl:"-"`
|
||||
|
||||
// License is the license used by HCP builds
|
||||
License string `hcl:"license"`
|
||||
}
|
||||
|
||||
func (c *Controller) InitNameIfEmpty() error {
|
||||
@@ -854,6 +859,12 @@ func Parse(d string) (*Config, error) {
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range extraParsingFuncs {
|
||||
if err := f(result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
stderror "errors"
|
||||
"net"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -13,6 +14,8 @@ import (
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
var errStateNotFound = stderror.New("no state attached to the connection")
|
||||
|
||||
// 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.
|
||||
@@ -48,11 +51,11 @@ func GetWorkerInfoFromStateMap(ctx context.Context, c net.Conn) (*WorkerConnecti
|
||||
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")
|
||||
return nil, errors.Wrap(ctx, errStateNotFound, op, errors.WithMsg("conn is not a state provider"))
|
||||
}
|
||||
st := pc.State()
|
||||
if st == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "no state attached to connection")
|
||||
return nil, errors.Wrap(ctx, errStateNotFound, op, errors.WithMsg("no state attached to connection"))
|
||||
}
|
||||
if err := mapstructure.Decode(st.AsMap(), &downstreamInfo); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestWorkerConnectionInfo_errors(t *testing.T) {
|
||||
t.Run("wrong connection type", func(t *testing.T) {
|
||||
c, _ := net.Pipe()
|
||||
got, err := GetWorkerInfoFromStateMap(context.Background(), c)
|
||||
assert.ErrorContains(t, err, "connection does not provide a State structpb.Struct")
|
||||
assert.ErrorContains(t, err, "conn is not a state provider")
|
||||
assert.Nil(t, got)
|
||||
})
|
||||
t.Run("no state on connection", func(t *testing.T) {
|
||||
|
||||
@@ -6,11 +6,13 @@ package cluster
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
"github.com/hashicorp/boundary/version"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/protocol"
|
||||
)
|
||||
@@ -65,8 +67,31 @@ func (e *trackingListener) Accept() (net.Conn, error) {
|
||||
case *protocol.Conn:
|
||||
tlsConn = c.Conn
|
||||
wi, err := GetWorkerInfoFromStateMap(e.ctx, c)
|
||||
if err != nil || wi == nil || len(wi.WorkerId) == 0 {
|
||||
event.WriteSysEvent(e.ctx, op, "did not get worker information from state map")
|
||||
switch {
|
||||
case err != nil && errors.Is(err, errStateNotFound) && !version.SupportsFeature(version.Binary, version.RequireVersionInWorkerInfo):
|
||||
// This will cause us to break below
|
||||
wi = new(WorkerConnectionInfo)
|
||||
case err != nil:
|
||||
// We want to check that if we are supporting metadata that it is supplied
|
||||
innerErr := fmt.Errorf("error trying to get worker information from state map: %w", err)
|
||||
event.WriteError(e.ctx, op, innerErr)
|
||||
conn.Close()
|
||||
return conn, nil
|
||||
case wi == nil:
|
||||
event.WriteError(e.ctx, op, stderrors.New("nil worker info in state map"))
|
||||
conn.Close()
|
||||
return conn, nil
|
||||
case version.Get().VersionMetadata != "":
|
||||
incomingVer := version.FromVersionString(wi.BoundaryVersion)
|
||||
if (incomingVer == nil || incomingVer.VersionMetadata == "") && version.SupportsFeature(version.Binary, version.RequireVersionInWorkerInfo) {
|
||||
err := stderrors.New("build contains version with metadata, incoming worker version is nil or has mismatched metadata")
|
||||
event.WriteError(e.ctx, op, err)
|
||||
conn.Close()
|
||||
return conn, nil
|
||||
}
|
||||
}
|
||||
if len(wi.WorkerId) == 0 {
|
||||
event.WriteSysEvent(e.ctx, op, "did not find worker id in state map")
|
||||
break
|
||||
}
|
||||
workerId = wi.WorkerId
|
||||
@@ -75,15 +100,18 @@ func (e *trackingListener) Accept() (net.Conn, error) {
|
||||
tlsConn = c
|
||||
default:
|
||||
event.WriteError(e.ctx, op, fmt.Errorf("unexpected connection type: %T", c), event.WithInfo(eventingOpts...))
|
||||
conn.Close()
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
if tlsConn == nil {
|
||||
event.WriteError(e.ctx, op, fmt.Errorf("nil tlsConn"), event.WithInfo(eventingOpts...))
|
||||
conn.Close()
|
||||
return conn, nil
|
||||
}
|
||||
if len(tlsConn.ConnectionState().PeerCertificates) == 0 {
|
||||
event.WriteError(e.ctx, op, fmt.Errorf("tls conn without any peer certificates"), event.WithInfo(eventingOpts...))
|
||||
conn.Close()
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
@@ -93,7 +121,7 @@ func (e *trackingListener) Accept() (net.Conn, error) {
|
||||
}
|
||||
if keyId == "" {
|
||||
// No key id means there is nothing to track.
|
||||
event.WriteError(e.ctx, op, fmt.Errorf("no key id found for connection"), event.WithInfo(eventingOpts...))
|
||||
event.WriteError(e.ctx, op, stderrors.New("no key id found for connection"), event.WithInfo(eventingOpts...))
|
||||
return conn, nil
|
||||
}
|
||||
eventingOpts = append(eventingOpts, "key_id", keyId)
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
nodee "github.com/hashicorp/nodeenrollment"
|
||||
"github.com/hashicorp/nodeenrollment/protocol"
|
||||
)
|
||||
|
||||
// EventingListener simply sends an event when a worker has connected
|
||||
// successfully
|
||||
type eventingListener struct {
|
||||
ctx context.Context
|
||||
baseLn net.Listener
|
||||
}
|
||||
|
||||
func NewEventingListener(ctx context.Context, baseLn net.Listener) (net.Listener, error) {
|
||||
const op = "common.(EventingListener).Accept"
|
||||
switch {
|
||||
case ctx == nil:
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil context")
|
||||
case baseLn == nil:
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil base listener")
|
||||
}
|
||||
return &eventingListener{
|
||||
ctx: ctx,
|
||||
baseLn: baseLn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *eventingListener) Accept() (net.Conn, error) {
|
||||
const op = "common.(EventingListener).Accept"
|
||||
conn, err := e.baseLn.Accept()
|
||||
if err != nil || conn == nil {
|
||||
return conn, err
|
||||
}
|
||||
|
||||
var tlsConn *tls.Conn
|
||||
switch c := conn.(type) {
|
||||
case *tls.Conn:
|
||||
tlsConn = c
|
||||
case *protocol.Conn:
|
||||
tlsConn = c.Conn
|
||||
default:
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
if tlsConn != nil && len(tlsConn.ConnectionState().PeerCertificates) > 0 {
|
||||
keyId, err := nodee.KeyIdFromPkix(tlsConn.ConnectionState().PeerCertificates[0].SubjectKeyId)
|
||||
if err == nil {
|
||||
event.WriteSysEvent(e.ctx, op, "worker successfully authenticated", "key_id", keyId)
|
||||
}
|
||||
}
|
||||
|
||||
return conn, err
|
||||
}
|
||||
|
||||
func (e *eventingListener) Close() error {
|
||||
return e.baseLn.Close()
|
||||
}
|
||||
|
||||
func (e *eventingListener) Addr() net.Addr {
|
||||
return e.baseLn.Addr()
|
||||
}
|
||||
@@ -95,6 +95,7 @@ var (
|
||||
action.List,
|
||||
}
|
||||
|
||||
validateCredentialSourcesFn = func(context.Context, subtypes.Subtype, []target.CredentialSource) error { return nil }
|
||||
ValidateIngressWorkerFilterFn = IngressWorkerFilterUnsupported
|
||||
AuthorizeSessionWorkerFilterFn = AuthorizeSessionWithWorkerFilter
|
||||
WorkerFilterDeprecationMessage = fmt.Sprintf("This field is deprecated. Use %s instead.", globals.EgressWorkerFilterField)
|
||||
@@ -721,6 +722,11 @@ func (s Service) AuthorizeSession(ctx context.Context, req *pbs.AuthorizeSession
|
||||
if t == nil {
|
||||
return nil, handlers.NotFoundErrorf("Target %q not found.", t.GetPublicId())
|
||||
}
|
||||
if len(credSources) > 0 {
|
||||
if err := validateCredentialSourcesFn(ctx, t.GetType(), credSources); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate some repos
|
||||
sessionRepo, err := s.sessionRepoFn()
|
||||
|
||||
@@ -162,16 +162,10 @@ func (c *Controller) configureForCluster(ln *base.ServerListener) (func(), error
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error instantiating node enrollment authed split listener: %w", err)
|
||||
}
|
||||
// This wraps the normal worker connections with something that events with
|
||||
// the worker ID on successful auth/connection
|
||||
eventingAuthedListener, err := common.NewEventingListener(c.baseContext, nodeeAuthedListener)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error creating eventing listener: %w", op, err)
|
||||
}
|
||||
|
||||
// This wraps the normal pki worker connections with a listener which adds
|
||||
// the worker key id of the connections to the controller's pkiConnManager.
|
||||
pkiWorkerTrackingListener, err := cluster.NewTrackingListener(c.baseContext, eventingAuthedListener, c.pkiConnManager, sourcePurpose(grpcListenerPurpose))
|
||||
pkiWorkerTrackingListener, err := cluster.NewTrackingListener(c.baseContext, nodeeAuthedListener, c.pkiConnManager, sourcePurpose(grpcListenerPurpose))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error creating pki worker tracking listener: %w", op, err)
|
||||
}
|
||||
|
||||
@@ -23,13 +23,16 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/authtoken"
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
"github.com/hashicorp/boundary/internal/cmd/config"
|
||||
"github.com/hashicorp/boundary/internal/credential/vault"
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
"github.com/hashicorp/boundary/internal/gen/testing/interceptor"
|
||||
"github.com/hashicorp/boundary/internal/host/plugin"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/intglobals"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
"github.com/hashicorp/boundary/internal/scheduler"
|
||||
"github.com/hashicorp/boundary/internal/server"
|
||||
"github.com/hashicorp/boundary/internal/session"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
@@ -134,6 +137,26 @@ func (tc *TestController) ConnectionsRepo() *session.ConnectionRepository {
|
||||
return repo
|
||||
}
|
||||
|
||||
func (tc *TestController) PluginHostRepo() *plugin.Repository {
|
||||
repo, err := tc.c.PluginHostRepoFn()
|
||||
if err != nil {
|
||||
tc.t.Fatal(err)
|
||||
}
|
||||
return repo
|
||||
}
|
||||
|
||||
func (tc *TestController) VaultCredentialRepo() *vault.Repository {
|
||||
repo, err := tc.c.VaultCredentialRepoFn()
|
||||
if err != nil {
|
||||
tc.t.Fatal(err)
|
||||
}
|
||||
return repo
|
||||
}
|
||||
|
||||
func (tc *TestController) Scheduler() *scheduler.Scheduler {
|
||||
return tc.Controller().scheduler
|
||||
}
|
||||
|
||||
func (tc *TestController) Cancel() {
|
||||
tc.cancel()
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
"github.com/hashicorp/boundary/internal/server"
|
||||
"github.com/hashicorp/boundary/version"
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
@@ -71,6 +73,7 @@ func (c Controller) validateWorkerTls(hello *tls.ClientHelloInfo) (*tls.Config,
|
||||
// * Ensures that the nonce is unique to prevent replay attacks
|
||||
// * Returns the shared TLS configuration that is used to establish the connection
|
||||
func (c Controller) v1WorkerAuthConfig(protos []string) (*tls.Config, *base.WorkerAuthInfo, error) {
|
||||
const op = "controller.(Controller).v1WorkerAuthConfig"
|
||||
var firstMatchProto string
|
||||
var encString string
|
||||
for _, p := range protos {
|
||||
@@ -104,6 +107,14 @@ func (c Controller) v1WorkerAuthConfig(protos []string) (*tls.Config, *base.Work
|
||||
if err := json.Unmarshal(marshaledInfo, info); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if version.Get().VersionMetadata != "" {
|
||||
incomingVer := version.FromVersionString(info.BoundaryVersion)
|
||||
if (incomingVer == nil || incomingVer.VersionMetadata == "") && version.SupportsFeature(version.Binary, version.RequireVersionInWorkerInfo) {
|
||||
err := errors.New("build contains version with metadata, incoming worker version is nil or has mismatched metadata")
|
||||
event.WriteError(c.baseContext, op, err)
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check for replays
|
||||
serversRepo, err := c.ServersRepoFn()
|
||||
|
||||
@@ -253,9 +253,10 @@ func (w *Worker) createClientConn(addr string) error {
|
||||
func (w *Worker) workerAuthTLSConfig(extraAlpnProtos ...string) (*tls.Config, *base.WorkerAuthInfo, error) {
|
||||
var err error
|
||||
info := &base.WorkerAuthInfo{
|
||||
Name: w.conf.RawConfig.Worker.Name,
|
||||
Description: w.conf.RawConfig.Worker.Description,
|
||||
ProxyAddress: w.conf.RawConfig.Worker.PublicAddr,
|
||||
Name: w.conf.RawConfig.Worker.Name,
|
||||
Description: w.conf.RawConfig.Worker.Description,
|
||||
ProxyAddress: w.conf.RawConfig.Worker.PublicAddr,
|
||||
BoundaryVersion: version.Get().VersionNumber(),
|
||||
}
|
||||
|
||||
info.ConnectionNonce, err = w.nonceFn(20)
|
||||
|
||||
@@ -230,14 +230,9 @@ func (w *Worker) configureForWorker(ln *base.ServerListener, logger *log.Logger,
|
||||
|
||||
ln.GrpcServer = downstreamServer
|
||||
|
||||
eventingListener, err := common.NewEventingListener(cancelCtx, nodeeAuthListener)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error creating eventing listener: %w", op, err)
|
||||
}
|
||||
|
||||
// This wraps the normal pki worker connections with a listener which adds
|
||||
// the worker key id of the connections to the worker's pkiConnManager.
|
||||
pkiWorkerTrackingListener, err := cluster.NewTrackingListener(cancelCtx, eventingListener, w.pkiConnManager, sourcePurpose(grpcListenerPurpose))
|
||||
pkiWorkerTrackingListener, err := cluster.NewTrackingListener(cancelCtx, nodeeAuthListener, w.pkiConnManager, sourcePurpose(grpcListenerPurpose))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: error creating pki worker tracking listener: %w", op, err)
|
||||
}
|
||||
|
||||
+13
-3
@@ -28,6 +28,15 @@ echo "==> Build tags: ${BUILD_TAGS}"
|
||||
GIT_COMMIT="$(git rev-parse HEAD)"
|
||||
GIT_DIRTY="$(test -n "`git status --porcelain`" && echo "+CHANGES" || true)"
|
||||
|
||||
# Get the build date from the latest commit since it can be used across all
|
||||
# builds
|
||||
function build_date() {
|
||||
# It's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC
|
||||
: "${DATE_FORMAT:="%Y-%m-%dT%H:%M:%SZ"}"
|
||||
git show --no-show-signature -s --format=%cd --date=format:"$DATE_FORMAT" HEAD
|
||||
}
|
||||
BUILD_DATE=$(build_date)
|
||||
|
||||
# If not explicitly cross-compiling, build for the current platform
|
||||
if [ "${GOOS}x" == "x" ]; then
|
||||
GOOS=$(go env GOOS)
|
||||
@@ -57,7 +66,7 @@ if [ "${CI_BUILD}x" != "x" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
PRODUCT_VERSION=${PRODUCT_VERSION:=$(cat version/VERSION)}
|
||||
BASE_PRODUCT_VERSION=${BASE_PRODUCT_VERSION:=$(cat version/VERSION)}
|
||||
|
||||
# Declare binary paths!
|
||||
BINARY_NAME="boundary${BINARY_SUFFIX}"
|
||||
@@ -77,10 +86,11 @@ ${GO_CMD} build \
|
||||
-trimpath \
|
||||
-buildvcs=false \
|
||||
-ldflags "
|
||||
-X github.com/hashicorp/boundary/version.GitCommit=${GIT_COMMIT}${GIT_DIRTY}
|
||||
-X 'github.com/hashicorp/boundary/version.Version=$PRODUCT_VERSION'
|
||||
-X 'github.com/hashicorp/boundary/version.GitCommit=${GIT_COMMIT}${GIT_DIRTY}'
|
||||
-X 'github.com/hashicorp/boundary/version.Version=$BASE_PRODUCT_VERSION'
|
||||
-X 'github.com/hashicorp/boundary/version.VersionPrerelease=$PRERELEASE_PRODUCT_VERSION'
|
||||
-X 'github.com/hashicorp/boundary/version.VersionMetadata=$METADATA_PRODUCT_VERSION'
|
||||
-X 'github.com/hashicorp/boundary/version.BuildDate=$BUILD_DATE'
|
||||
" \
|
||||
-o "$BIN_PATH" \
|
||||
./cmd/boundary
|
||||
|
||||
@@ -19,6 +19,7 @@ const (
|
||||
IncludeStatusInCli
|
||||
CredentialLibraryVaultSubtype
|
||||
UseTargetIdForHostId
|
||||
RequireVersionInWorkerInfo
|
||||
)
|
||||
|
||||
var featureMap map[Feature]MetadataConstraint
|
||||
@@ -62,6 +63,11 @@ func init() {
|
||||
featureMap[UseTargetIdForHostId] = MetadataConstraint{
|
||||
Constraints: mustNewConstraints("< 0.14.0"),
|
||||
}
|
||||
// RequireVersionInWorkerInfo allows us to take action on various workers
|
||||
// based on their version, e.g. to prevent incompatibilities
|
||||
featureMap[RequireVersionInWorkerInfo] = MetadataConstraint{
|
||||
Constraints: mustNewConstraints(">= 0.13.0"),
|
||||
}
|
||||
}
|
||||
|
||||
func mustNewConstraints(v string) gvers.Constraints {
|
||||
|
||||
@@ -19,6 +19,7 @@ type Info struct {
|
||||
Version string `json:"version,omitempty"`
|
||||
VersionPrerelease string `json:"version_prerelease,omitempty"`
|
||||
VersionMetadata string `json:"version_metadata,omitempty"`
|
||||
BuildDate string `json:"build_date,omitempty"`
|
||||
CgoEnabled bool `json:"cgo_enabled,omitempty"`
|
||||
}
|
||||
|
||||
@@ -26,6 +27,7 @@ func Get() *Info {
|
||||
ver := Version
|
||||
rel := VersionPrerelease
|
||||
md := VersionMetadata
|
||||
bd := BuildDate
|
||||
if GitDescribe != "" {
|
||||
ver = GitDescribe
|
||||
}
|
||||
@@ -43,6 +45,7 @@ func Get() *Info {
|
||||
Version: ver,
|
||||
VersionPrerelease: rel,
|
||||
VersionMetadata: md,
|
||||
BuildDate: bd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,12 @@ var (
|
||||
Version = "0.12.0"
|
||||
|
||||
// VersionPrerelease is also set at compile time, similarly to Version.
|
||||
VersionPrerelease = ""
|
||||
VersionPrerelease string
|
||||
|
||||
// VersionMetadata is also set at compile time.
|
||||
VersionMetadata = ""
|
||||
VersionMetadata string
|
||||
|
||||
// BuildDate is the date of the build, which corresponds to the timestamp of
|
||||
// the most recent commit
|
||||
BuildDate string
|
||||
)
|
||||
Reference in new issue
Block a user