Filter WorkerList by feature and go from version string to version.Info (#2807)
This commit is contained in:
7 files changed
+190
-5
No files matched your search
@@ -276,6 +276,9 @@ func TestAuthorizeConnection(t *testing.T) {
|
||||
require.NoError(t, kmsCache.CreateKeys(context.Background(), scope.Global.String(), kms.WithRandomReader(rand.Reader)))
|
||||
|
||||
currentConnFn := connectionRouteFn
|
||||
t.Cleanup(func() {
|
||||
connectionRouteFn = currentConnFn
|
||||
})
|
||||
connectionRouteFn = singleHopConnectionRoute
|
||||
|
||||
org, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
|
||||
@@ -422,7 +425,6 @@ func TestAuthorizeConnection(t *testing.T) {
|
||||
assert.Empty(t, cmp.Diff(resp, tc.want, protocmp.Transform()))
|
||||
})
|
||||
}
|
||||
connectionRouteFn = currentConnFn
|
||||
}
|
||||
|
||||
func TestCancelSession(t *testing.T) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/handlers"
|
||||
"github.com/hashicorp/boundary/internal/server"
|
||||
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
|
||||
"github.com/hashicorp/boundary/version"
|
||||
"github.com/hashicorp/go-bexpr"
|
||||
"github.com/mitchellh/pointerstructure"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -43,6 +44,19 @@ func (w WorkerList) WorkerInfos() []*pb.WorkerInfo {
|
||||
return ret
|
||||
}
|
||||
|
||||
// SupportsFeature returns a new WorkerList composed of all workers in this
|
||||
// WorkerList which supports the provided feature.
|
||||
func (w WorkerList) SupportsFeature(f version.Feature) WorkerList {
|
||||
var ret []*server.Worker
|
||||
for _, worker := range w {
|
||||
sv := version.FromVersionString(worker.GetReleaseVersion()).Semver()
|
||||
if version.SupportsFeature(sv, f) {
|
||||
ret = append(ret, worker)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// filtered returns a new workerList where all elements contained in it are the
|
||||
// ones which from the original workerList that pass the evaluator's evaluation.
|
||||
func (w WorkerList) Filtered(eval *bexpr.Evaluator) (WorkerList, error) {
|
||||
|
||||
@@ -625,7 +625,7 @@ func (s Service) RemoveTargetCredentialSources(ctx context.Context, req *pbs.Rem
|
||||
|
||||
// If set, use the worker_filter or egress_worker_filter to filtere the selected workers
|
||||
// and ensure we have workers available to service this request.
|
||||
func AuthorizeSessionWithWorkerFilter(_ context.Context, t target.Target, selectedWorkers []*server.Worker, _ common.Downstreamers) ([]*server.Worker, error) {
|
||||
func AuthorizeSessionWithWorkerFilter(_ context.Context, t target.Target, selectedWorkers wl.WorkerList, _ common.Downstreamers) (wl.WorkerList, error) {
|
||||
if len(selectedWorkers) > 0 {
|
||||
var eval *bexpr.Evaluator
|
||||
var err error
|
||||
@@ -641,7 +641,7 @@ func AuthorizeSessionWithWorkerFilter(_ context.Context, t target.Target, select
|
||||
return nil, err
|
||||
}
|
||||
|
||||
selectedWorkers, err = wl.WorkerList(selectedWorkers).Filtered(eval)
|
||||
selectedWorkers, err = selectedWorkers.Filtered(eval)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -109,13 +109,14 @@ session_connection_limit(expiration_time, connection_limit) as (
|
||||
select
|
||||
s.expiration_time,
|
||||
s.connection_limit,
|
||||
s.egress_worker_filter
|
||||
s.egress_worker_filter,
|
||||
s.ingress_worker_filter
|
||||
from
|
||||
session s
|
||||
where
|
||||
s.public_id = @session_id
|
||||
)
|
||||
select expiration_time, connection_limit, egress_worker_filter, current_connection_count
|
||||
select expiration_time, connection_limit, egress_worker_filter, ingress_worker_filter, current_connection_count
|
||||
from
|
||||
session_connection_limit, session_connection_count;
|
||||
`
|
||||
|
||||
@@ -446,6 +446,7 @@ type AuthzSummary struct {
|
||||
ConnectionLimit int32
|
||||
CurrentConnectionCount uint32
|
||||
EgressWorkerFilter string
|
||||
IngressWorkerFilter string
|
||||
}
|
||||
|
||||
func (r *Repository) sessionAuthzSummary(ctx context.Context, sessionId string) (*AuthzSummary, error) {
|
||||
|
||||
@@ -3,6 +3,9 @@ package version
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
gvers "github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
const BoundaryPrefix = "Boundary v"
|
||||
@@ -54,6 +57,52 @@ func (c *Info) VersionNumber() string {
|
||||
return version
|
||||
}
|
||||
|
||||
// Semver returns a *gvers.Version if the Info is parseable as
|
||||
// a semantic version. Otherwise it returns nil.
|
||||
func (c *Info) Semver() *gvers.Version {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
v, err := gvers.NewSemver(c.VersionNumber())
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// FromVersionString returns an *Info containing the version, or nil if the
|
||||
// string was unable to be parsed.
|
||||
func FromVersionString(s string) *Info {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.TrimPrefix(s, BoundaryPrefix)
|
||||
i := Info{}
|
||||
|
||||
// Get the revision
|
||||
startOfRevIdx := strings.LastIndex(s, "(")
|
||||
endOfRevIdx := strings.LastIndex(s, ")")
|
||||
if startOfRevIdx > 0 && endOfRevIdx > 0 {
|
||||
if endOfRevIdx < startOfRevIdx {
|
||||
return nil
|
||||
}
|
||||
i.Revision, s = s[startOfRevIdx+1:endOfRevIdx], strings.TrimSpace(s[:startOfRevIdx])
|
||||
}
|
||||
|
||||
v, err := gvers.NewSemver(s)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if md := v.Metadata(); len(md) > 0 {
|
||||
i.VersionMetadata = md
|
||||
}
|
||||
if pr := v.Prerelease(); len(pr) > 0 {
|
||||
i.VersionPrerelease = pr
|
||||
}
|
||||
i.Version = v.Core().String()
|
||||
|
||||
return &i
|
||||
}
|
||||
|
||||
func (c *Info) FullVersionNumber(rev bool) string {
|
||||
var versionString bytes.Buffer
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
gvers "github.com/hashicorp/go-version"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFromVersionString(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
want *Info
|
||||
}{
|
||||
{
|
||||
input: "Boundary v0.12.0-beta+hcp.int (revision)",
|
||||
want: &Info{
|
||||
Revision: "revision",
|
||||
Version: "0.12.0",
|
||||
VersionPrerelease: "beta",
|
||||
VersionMetadata: "hcp.int",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "Boundary v0.12.0+hcp.int",
|
||||
want: &Info{
|
||||
Version: "0.12.0",
|
||||
VersionMetadata: "hcp.int",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "Boundary v0.12.0",
|
||||
want: &Info{
|
||||
Version: "0.12.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "0.12.0-alpha+hcp.int (revision)",
|
||||
want: &Info{
|
||||
Revision: "revision",
|
||||
Version: "0.12.0",
|
||||
VersionPrerelease: "alpha",
|
||||
VersionMetadata: "hcp.int",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: " 0.12.0-hcp+int ",
|
||||
want: &Info{
|
||||
Version: "0.12.0",
|
||||
VersionPrerelease: "hcp",
|
||||
VersionMetadata: "int",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "0.12.0- spaces in the prerelease are invalid",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
input: "Boundary (version unknown)",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
input: "(version unknown)",
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
got := FromVersionString(tc.input)
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSemver(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
toTest *Info
|
||||
want *gvers.Version
|
||||
}{
|
||||
{
|
||||
name: "0.12.0+hcp.int",
|
||||
toTest: &Info{
|
||||
Version: "0.12.0",
|
||||
VersionMetadata: "hcp.int",
|
||||
},
|
||||
want: gvers.Must(gvers.NewSemver("0.12.0+hcp.int")),
|
||||
},
|
||||
{
|
||||
name: "0.12.0+hcp.int (revision)",
|
||||
toTest: &Info{
|
||||
Version: "0.12.0",
|
||||
VersionMetadata: "hcp.int",
|
||||
Revision: "revision",
|
||||
},
|
||||
want: gvers.Must(gvers.NewSemver("0.12.0+hcp.int")),
|
||||
},
|
||||
{
|
||||
name: "unparsable",
|
||||
toTest: &Info{
|
||||
Version: "some unparsable string",
|
||||
VersionMetadata: "hcp.int",
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "nil info",
|
||||
toTest: nil,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := tc.toTest.Semver()
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user