Merge branch 'main' into plugin-hostcatalogs

# Conflicts:
#	go.mod
#	sdk/go.mod
pull/1692/head^2
Todd Knight 5 years ago
commit 884e1f2d18

@ -140,7 +140,8 @@ protobuild:
@protoc-go-inject-tag -input=./internal/gen/controller/api/services/auth_method_service.pb.go
@protoc-go-inject-tag -input=./sdk/pbs/controller/api/resources/authmethods/auth_method.pb.go
@protoc-go-inject-tag -input=./sdk/pbs/controller/api/resources/scopes/scope.pb.go
@protoc-go-inject-tag -input=./internal/gen/controller/servers/services/session_service.pb.go
@protoc-go-inject-tag -input=./sdk/pbs/controller/api/resources/targets/target.pb.go
# these protos, services and openapi artifacts are purely for testing purposes
@protoc-go-inject-tag -input=./internal/gen/testing/event/event.pb.go

@ -24,7 +24,7 @@ require (
github.com/hashicorp/cap v0.1.1
github.com/hashicorp/dawdle v0.4.0
github.com/hashicorp/dbassert v0.0.0-20210708202608-ecf920cf1ed8
github.com/hashicorp/eventlogger v0.1.1-0.20211104100552-e1e801e50144
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c
github.com/hashicorp/eventlogger/filters/encrypt v0.1.6-0.20211027211326-5db60a48f239
github.com/hashicorp/go-bexpr v0.1.10
github.com/hashicorp/go-cleanhttp v0.5.2

@ -477,8 +477,9 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/eventlogger v0.1.0/go.mod h1:a3IXf1aEJfpCPzseTOrwKj4fVW/Qn3oEmpQeaIznzH0=
github.com/hashicorp/eventlogger v0.1.1-0.20211104100552-e1e801e50144 h1:PCl0HtlVnIIloIozAKvjICu6K4IghKXAKNny3R3b2nI=
github.com/hashicorp/eventlogger v0.1.1-0.20211104100552-e1e801e50144/go.mod h1:a3IXf1aEJfpCPzseTOrwKj4fVW/Qn3oEmpQeaIznzH0=
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c h1:u1Zq+LfTXaagmJCHK3XH/fi7pk7oRY933VjGNG7/Ynw=
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c/go.mod h1:NaXU8p/pl5a2RX/N0/yncinT3Iw5CLkbF4JRxAVnk3c=
github.com/hashicorp/eventlogger/filters/encrypt v0.1.6-0.20211027211326-5db60a48f239 h1:Yh9tY0lige+y0trmjQeT9NRDo6+YvtNAzbmUNOsIUzI=
github.com/hashicorp/eventlogger/filters/encrypt v0.1.6-0.20211027211326-5db60a48f239/go.mod h1:8rcez7Kw1zanB0/074qnOuGu7zxmNh9Xr2ZI+K4xVIA=
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=

@ -463,14 +463,15 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ..
// which almost always should be to rollback. Update returns the number of
// rows updated.
//
// Supported options: WithOplog, NewOplogMsg and WithVersion.
// Supported options: WithOplog, NewOplogMsg, WithWhere and WithVersion.
// WithOplog will write an oplog entry for the update. NewOplogMsg
// will return in-memory oplog message. WithOplog and NewOplogMsg cannot be
// used together. If WithVersion is used, then the update will include the
// version number in the update where clause, which basically makes the update
// use optimistic locking and the update will only succeed if the existing rows
// version matches the WithVersion option. Zero is not a valid value for the
// WithVersion option and will return an error.
// WithVersion option and will return an error. WithWhere allows specifying an
// additional constraint on the operation in addition to the PKs.
func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error) {
const op = "db.Update"
if rw.underlying == nil {
@ -620,8 +621,8 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
// Delete an object in the db with options: WithOplog, NewOplogMsg, WithWhere.
// WithOplog will write an oplog entry for the delete. NewOplogMsg will return
// in-memory oplog message. WithOplog and NewOplogMsg cannot be used together.
// WithWhere allows specifying a constraint. Delete returns the number of rows
// deleted and any errors.
//WithWhere allows specifying an additional constraint on the operation in
//addition to the PKs. Delete returns the number of rows deleted and any errors.
func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, error) {
const op = "db.Delete"
if rw.underlying == nil {

@ -19,6 +19,7 @@ func TestDb_Create_OnConflict(t *testing.T) {
wrapper := db.TestWrapper(t)
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
db.TestCreateTables(t, conn)
// create initial user for on conflict tests
id, err := db.NewPublicId("test-user")

@ -26,6 +26,7 @@ import (
func TestDb_UpdateUnsetField(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
rw := &Db{
underlying: db,
}
@ -49,6 +50,7 @@ func TestDb_UpdateUnsetField(t *testing.T) {
func TestDb_Update(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
now := &timestamp.Timestamp{Timestamp: timestamppb.Now()}
publicId, err := NewPublicId("testuser")
require.NoError(t, err)
@ -626,6 +628,7 @@ func (u *testUserWithVet) VetForWrite(ctx context.Context, r Reader, opType OpTy
func TestDb_Create(t *testing.T) {
// intentionally not run with t.Parallel so we don't need to use DoTx for the Create tests
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
t.Run("simple", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := Db{underlying: db}
@ -801,6 +804,7 @@ func TestDb_Create(t *testing.T) {
func TestDb_LookupByPublicId(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
t.Run("simple", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := Db{underlying: db}
@ -856,6 +860,7 @@ func TestDb_LookupByPublicId(t *testing.T) {
func TestDb_LookupWhere(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
t.Run("simple", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := Db{underlying: db}
@ -907,6 +912,7 @@ func TestDb_LookupWhere(t *testing.T) {
func TestDb_SearchWhere(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
knownUser := testUser(t, db, "zedUser", "", "")
type args struct {
@ -1059,6 +1065,7 @@ func TestDb_Exec(t *testing.T) {
t.Parallel()
t.Run("update", func(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
require := require.New(t)
w := Db{underlying: db}
id := testId(t)
@ -1078,6 +1085,7 @@ func TestDb_DoTx(t *testing.T) {
t.Parallel()
ctx := context.TODO()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
t.Run("valid-with-10-retries", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := &Db{underlying: db}
@ -1250,6 +1258,7 @@ func TestDb_DoTx(t *testing.T) {
func TestDb_Delete(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
newUser := func() *db_test.TestUser {
w := &Db{
underlying: db,
@ -1273,6 +1282,13 @@ func TestDb_Delete(t *testing.T) {
"resource-public-id": []string{publicId},
}
}
// seed some test users, so we won't just happen to get a false positive
// with only 1 entry in the db
for i := 0; i < 1000; i++ {
_ = newUser()
}
type args struct {
i *db_test.TestUser
opt []Option
@ -1285,6 +1301,7 @@ func TestDb_Delete(t *testing.T) {
args args
want int
wantOplog bool
wantFound bool
wantErr bool
wantErrIs errors.Code
}{
@ -1298,6 +1315,29 @@ func TestDb_Delete(t *testing.T) {
want: 1,
wantErr: false,
},
{
name: "with-where-no-delete",
underlying: db,
wrapper: TestWrapper(t),
args: args{
i: newUser(),
opt: []Option{WithWhere("1 = ?", 2)},
},
wantFound: true,
want: 0,
wantErr: false,
},
{
name: "with-where-and-delete",
underlying: db,
wrapper: TestWrapper(t),
args: args{
i: newUser(),
opt: []Option{WithWhere("1 = ?", 1)},
},
want: 1,
wantErr: false,
},
{
name: "valid-with-oplog",
underlying: db,
@ -1385,6 +1425,11 @@ func TestDb_Delete(t *testing.T) {
foundUser := tt.args.i.Clone().(*db_test.TestUser)
foundUser.PublicId = tt.args.i.PublicId
err = rw.LookupByPublicId(context.Background(), foundUser)
if tt.wantFound {
assert.NoError(err)
assert.Equal(tt.args.i.PublicId, foundUser.PublicId)
return
}
assert.Error(err)
assert.True(errors.Match(errors.T(errors.RecordNotFound), err))
@ -1475,6 +1520,7 @@ func TestDb_Delete(t *testing.T) {
func TestDb_ScanRows(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
t.Run("valid", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := Db{underlying: db}
@ -1502,6 +1548,7 @@ func TestDb_ScanRows(t *testing.T) {
func TestDb_Query(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
t.Run("valid", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
rw := Db{underlying: db}
@ -1530,6 +1577,7 @@ func TestDb_Query(t *testing.T) {
func TestDb_CreateItems(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
testOplogResourceId := testId(t)
createFn := func() []interface{} {
@ -1742,6 +1790,7 @@ func TestDb_CreateItems(t *testing.T) {
func TestDb_DeleteItems(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
testOplogResourceId := testId(t)
createFn := func() []interface{} {
@ -2031,6 +2080,7 @@ func testScooterAccessory(t *testing.T, conn *DB, scooterId, accessoryId uint32)
func TestDb_LookupById(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
scooter := testScooter(t, db, "", 0)
user := testUser(t, db, "", "", "")
accessory := testAccessory(t, db, "test accessory")
@ -2170,6 +2220,7 @@ func TestDb_LookupById(t *testing.T) {
func TestDb_GetTicket(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
type notReplayable struct{}
tests := []struct {
name string
@ -2229,6 +2280,7 @@ func TestDb_GetTicket(t *testing.T) {
func TestDb_WriteOplogEntryWith(t *testing.T) {
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
w := Db{underlying: db}
ticket, err := w.GetTicket(&db_test.TestUser{})
@ -2959,6 +3011,7 @@ func TestDb_oplogMsgsForItems(t *testing.T) {
func TestDb_lookupAfterWrite(t *testing.T) {
t.Parallel()
db, _ := TestSetup(t, "postgres")
TestCreateTables(t, db)
scooter := testScooter(t, db, "", 0)
user := testUser(t, db, "", "", "")
type args struct {

@ -0,0 +1,23 @@
begin;
-- remove the internal/db test tables from the migrations.
drop table if exists db_test_user cascade;
drop table if exists db_test_car cascade;
drop table if exists db_test_rental cascade;
drop table if exists db_test_scooter cascade;
drop table if exists db_test_accessory cascade;
drop table if exists db_test_scooter_accessory cascade;
delete from oplog_ticket where name in
(
'db_test_user',
'db_test_car',
'db_test_rental',
'db_test_scooter',
'db_test_accessory',
'db_test_scooter_accessory'
);
commit;

@ -17,6 +17,7 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm/logger"
)
@ -227,3 +228,255 @@ func WithTemplate(template string) TestOption {
o.withTemplate = template
}
}
// TestCreateTables will create the test tables for the db pkg
func TestCreateTables(t *testing.T, conn *DB) {
t.Helper()
t.Cleanup(func() { testDropTables(t, conn) })
require := require.New(t)
testCtx := context.Background()
rw := New(conn)
_, err := rw.Exec(testCtx, testQueryCreateTables, nil)
require.NoError(err)
_, err = rw.Exec(testCtx, testQueryAddOplogEntries, nil)
require.NoError(err)
}
func testDropTables(t *testing.T, conn *DB) {
t.Helper()
require := require.New(t)
testCtx := context.Background()
rw := New(conn)
_, err := rw.Exec(testCtx, testQueryDropTables, nil)
require.NoError(err)
_, err = rw.Exec(testCtx, testQueryDeleteOplogEntries, nil)
require.NoError(err)
}
const (
testQueryCreateTables = `
begin;
-- create test tables used in the unit tests for the internal/db package
-- these tables (db_test_user, db_test_car, db_test_rental, db_test_scooter) are
-- not part of the boundary domain model... they are simply used for testing
-- the internal/db package
create table if not exists db_test_user (
id bigint generated always as identity primary key,
create_time wt_timestamp,
update_time wt_timestamp,
public_id text not null unique,
name text unique,
phone_number text,
email text,
version wt_version
);
create trigger
update_time_column
before
update on db_test_user
for each row execute procedure update_time_column();
-- define the immutable fields for db_test_user
create trigger
immutable_columns
before
update on db_test_user
for each row execute procedure immutable_columns('create_time');
create trigger
default_create_time_column
before
insert on db_test_user
for each row execute procedure default_create_time();
create trigger
update_version_column
after update on db_test_user
for each row execute procedure update_version_column();
create table if not exists db_test_car (
id bigint generated always as identity primary key,
create_time wt_timestamp,
update_time wt_timestamp,
public_id text not null unique,
name text unique,
model text,
mpg smallint
);
create trigger
update_time_column
before
update on db_test_car
for each row execute procedure update_time_column();
-- define the immutable fields for db_test_car
create trigger
immutable_columns
before
update on db_test_car
for each row execute procedure immutable_columns('create_time');
create trigger
default_create_time_column
before
insert on db_test_car
for each row execute procedure default_create_time();
create table if not exists db_test_rental (
id bigint generated always as identity primary key,
create_time wt_timestamp,
update_time wt_timestamp,
public_id text not null unique,
name text unique,
user_id bigint not null references db_test_user(id),
car_id bigint not null references db_test_car(id)
);
create trigger
update_time_column
before
update on db_test_rental
for each row execute procedure update_time_column();
-- define the immutable fields for db_test_rental
create trigger
immutable_columns
before
update on db_test_rental
for each row execute procedure immutable_columns('create_time');
create trigger
default_create_time_column
before
insert on db_test_rental
for each row execute procedure default_create_time();
create table if not exists db_test_scooter (
id bigint generated always as identity primary key,
create_time wt_timestamp,
update_time wt_timestamp,
private_id text not null unique,
name text unique,
model text,
mpg smallint
);
create trigger
update_time_column
before
update on db_test_scooter
for each row execute procedure update_time_column();
-- define the immutable fields for db_test_scooter
create trigger
immutable_columns
before
update on db_test_scooter
for each row execute procedure immutable_columns('create_time');
create trigger
default_create_time_column
before
insert on db_test_scooter
for each row execute procedure default_create_time();
create table if not exists db_test_accessory (
accessory_id bigint generated always as identity primary key,
create_time wt_timestamp,
update_time wt_timestamp,
description text not null
);
create trigger
update_time_column
before
update on db_test_accessory
for each row execute procedure update_time_column();
create trigger
immutable_columns
before
update on db_test_accessory
for each row execute procedure immutable_columns('create_time');
create trigger
default_create_time_column
before
insert on db_test_accessory
for each row execute procedure default_create_time();
create table if not exists db_test_scooter_accessory (
accessory_id bigint references db_test_accessory(accessory_id),
scooter_id bigint references db_test_scooter(id),
create_time wt_timestamp,
update_time wt_timestamp,
review text,
primary key(accessory_id, scooter_id)
);
create trigger
update_time_column
before
update on db_test_scooter_accessory
for each row execute procedure update_time_column();
create trigger
immutable_columns
before
update on db_test_scooter_accessory
for each row execute procedure immutable_columns('create_time');
create trigger
default_create_time_column
before
insert on db_test_scooter_accessory
for each row execute procedure default_create_time();
commit;
`
testQueryDropTables = `
begin;
drop table if exists db_test_user cascade;
drop table if exists db_test_car cascade;
drop table if exists db_test_rental cascade;
drop table if exists db_test_scooter cascade;
drop table if exists db_test_accessory cascade;
drop table if exists db_test_scooter_accessory cascade;
commit;
`
testQueryAddOplogEntries = `
begin;
insert into oplog_ticket (name, version)
values
('db_test_user', 1),
('db_test_car', 1),
('db_test_rental', 1),
('db_test_scooter', 1),
('db_test_accessory', 1),
('db_test_scooter_accessory', 1);
commit;
`
testQueryDeleteOplogEntries = `
begin;
delete from oplog_ticket where name in
(
'db_test_user',
'db_test_car',
'db_test_rental',
'db_test_scooter',
'db_test_accessory',
'db_test_scooter_accessory'
);
commit;
`
)

@ -23,6 +23,7 @@ func Test_Utils(t *testing.T) {
func TestVerifyOplogEntry(t *testing.T) {
db, _ := TestSetup(t, "postgres")
assert := assert.New(t)
TestCreateTables(t, db)
t.Run("valid", func(t *testing.T) {
rw := Db{underlying: db}

@ -28,10 +28,10 @@ type LookupSessionRequest struct {
unknownFields protoimpl.UnknownFields
// The session ID from the client
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty" class:"public"` // @gotags: `class:"public"`
// The name of the requesting worker, used for filtering to ensure this
// worker is allowed to handle this session.
ServerId string `protobuf:"bytes,20,opt,name=server_id,json=serverId,proto3" json:"server_id,omitempty"`
ServerId string `protobuf:"bytes,20,opt,name=server_id,json=serverId,proto3" json:"server_id,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *LookupSessionRequest) Reset() {
@ -88,17 +88,17 @@ type LookupSessionResponse struct {
unknownFields protoimpl.UnknownFields
Authorization *targets.SessionAuthorizationData `protobuf:"bytes,10,opt,name=authorization,proto3" json:"authorization,omitempty"`
TofuToken string `protobuf:"bytes,20,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty"`
Version uint32 `protobuf:"varint,30,opt,name=version,proto3" json:"version,omitempty"`
Endpoint string `protobuf:"bytes,40,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
Expiration *timestamppb.Timestamp `protobuf:"bytes,50,opt,name=expiration,proto3" json:"expiration,omitempty"`
Status SESSIONSTATUS `protobuf:"varint,60,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty"`
ConnectionLimit int32 `protobuf:"varint,70,opt,name=connection_limit,json=connectionLimit,proto3" json:"connection_limit,omitempty"`
ConnectionsLeft int32 `protobuf:"varint,80,opt,name=connections_left,json=connectionsLeft,proto3" json:"connections_left,omitempty"`
HostId string `protobuf:"bytes,90,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty"`
HostSetId string `protobuf:"bytes,100,opt,name=host_set_id,json=hostSetId,proto3" json:"host_set_id,omitempty"`
TargetId string `protobuf:"bytes,110,opt,name=target_id,json=targetId,proto3" json:"target_id,omitempty"`
UserId string `protobuf:"bytes,120,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
TofuToken string `protobuf:"bytes,20,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty" class:"secret"` // @gotags: `class:"secret"`
Version uint32 `protobuf:"varint,30,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
Endpoint string `protobuf:"bytes,40,opt,name=endpoint,proto3" json:"endpoint,omitempty" class:"public"` // @gotags: `class:"public"`
Expiration *timestamppb.Timestamp `protobuf:"bytes,50,opt,name=expiration,proto3" json:"expiration,omitempty" class:"public"` // @gotags: `class:"public"`
Status SESSIONSTATUS `protobuf:"varint,60,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
ConnectionLimit int32 `protobuf:"varint,70,opt,name=connection_limit,json=connectionLimit,proto3" json:"connection_limit,omitempty" class:"public"` // @gotags: `class:"public"`
ConnectionsLeft int32 `protobuf:"varint,80,opt,name=connections_left,json=connectionsLeft,proto3" json:"connections_left,omitempty" class:"public"` // @gotags: `class:"public"`
HostId string `protobuf:"bytes,90,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty" class:"public"` // @gotags: `class:"public"`
HostSetId string `protobuf:"bytes,100,opt,name=host_set_id,json=hostSetId,proto3" json:"host_set_id,omitempty" class:"public"` // @gotags: `class:"public"`
TargetId string `protobuf:"bytes,110,opt,name=target_id,json=targetId,proto3" json:"target_id,omitempty" class:"public"` // @gotags: `class:"public"`
UserId string `protobuf:"bytes,120,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *LookupSessionResponse) Reset() {
@ -222,11 +222,11 @@ type ActivateSessionRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
TofuToken string `protobuf:"bytes,20,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty"`
Version uint32 `protobuf:"varint,30,opt,name=version,proto3" json:"version,omitempty"`
WorkerId string `protobuf:"bytes,40,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"`
Status SESSIONSTATUS `protobuf:"varint,50,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty"`
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty" class:"public"` // @gotags: `class:"public"`
TofuToken string `protobuf:"bytes,20,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty" class:"secret"` // @gotags: `class:"secret"`
Version uint32 `protobuf:"varint,30,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
WorkerId string `protobuf:"bytes,40,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty" class:"public"` // @gotags: `class:"public"`
Status SESSIONSTATUS `protobuf:"varint,50,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *ActivateSessionRequest) Reset() {
@ -301,7 +301,7 @@ type ActivateSessionResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status SESSIONSTATUS `protobuf:"varint,10,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty"`
Status SESSIONSTATUS `protobuf:"varint,10,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *ActivateSessionResponse) Reset() {
@ -348,7 +348,7 @@ type CancelSessionRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *CancelSessionRequest) Reset() {
@ -395,7 +395,7 @@ type CancelSessionResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status SESSIONSTATUS `protobuf:"varint,10,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty"`
Status SESSIONSTATUS `protobuf:"varint,10,opt,name=status,proto3,enum=controller.servers.services.v1.SESSIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *CancelSessionResponse) Reset() {
@ -442,8 +442,8 @@ type AuthorizeConnectionRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
WorkerId string `protobuf:"bytes,20,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"`
SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty" class:"public"` // @gotags: `class:"public"`
WorkerId string `protobuf:"bytes,20,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *AuthorizeConnectionRequest) Reset() {
@ -497,9 +497,9 @@ type AuthorizeConnectionResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
Status CONNECTIONSTATUS `protobuf:"varint,20,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty"`
ConnectionsLeft int32 `protobuf:"varint,30,opt,name=connections_left,json=connectionsLeft,proto3" json:"connections_left,omitempty"`
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" class:"public"` // @gotags: `class:"public"`
Status CONNECTIONSTATUS `protobuf:"varint,20,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
ConnectionsLeft int32 `protobuf:"varint,30,opt,name=connections_left,json=connectionsLeft,proto3" json:"connections_left,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *AuthorizeConnectionResponse) Reset() {
@ -560,12 +560,12 @@ type ConnectConnectionRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
ClientTcpAddress string `protobuf:"bytes,20,opt,name=client_tcp_address,json=clientTcpAddress,proto3" json:"client_tcp_address,omitempty"`
ClientTcpPort uint32 `protobuf:"varint,30,opt,name=client_tcp_port,json=clientTcpPort,proto3" json:"client_tcp_port,omitempty"`
EndpointTcpAddress string `protobuf:"bytes,40,opt,name=endpoint_tcp_address,json=endpointTcpAddress,proto3" json:"endpoint_tcp_address,omitempty"`
EndpointTcpPort uint32 `protobuf:"varint,50,opt,name=endpoint_tcp_port,json=endpointTcpPort,proto3" json:"endpoint_tcp_port,omitempty"`
Type string `protobuf:"bytes,60,opt,name=type,proto3" json:"type,omitempty"`
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" class:"public"` // @gotags: `class:"public"`
ClientTcpAddress string `protobuf:"bytes,20,opt,name=client_tcp_address,json=clientTcpAddress,proto3" json:"client_tcp_address,omitempty" class:"public"` // @gotags: `class:"public"`
ClientTcpPort uint32 `protobuf:"varint,30,opt,name=client_tcp_port,json=clientTcpPort,proto3" json:"client_tcp_port,omitempty" class:"public"` // @gotags: `class:"public"`
EndpointTcpAddress string `protobuf:"bytes,40,opt,name=endpoint_tcp_address,json=endpointTcpAddress,proto3" json:"endpoint_tcp_address,omitempty" class:"public"` // @gotags: `class:"public"`
EndpointTcpPort uint32 `protobuf:"varint,50,opt,name=endpoint_tcp_port,json=endpointTcpPort,proto3" json:"endpoint_tcp_port,omitempty" class:"public"` // @gotags: `class:"public"`
Type string `protobuf:"bytes,60,opt,name=type,proto3" json:"type,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *ConnectConnectionRequest) Reset() {
@ -647,7 +647,7 @@ type ConnectConnectionResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status CONNECTIONSTATUS `protobuf:"varint,10,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty"`
Status CONNECTIONSTATUS `protobuf:"varint,10,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *ConnectConnectionResponse) Reset() {
@ -694,10 +694,10 @@ type CloseConnectionRequestData struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
BytesUp uint64 `protobuf:"varint,20,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty"`
BytesDown uint64 `protobuf:"varint,30,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty"`
Reason string `protobuf:"bytes,40,opt,name=reason,proto3" json:"reason,omitempty"`
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" class:"public"` // @gotags: `class:"public"`
BytesUp uint64 `protobuf:"varint,20,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
BytesDown uint64 `protobuf:"varint,30,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
Reason string `protobuf:"bytes,40,opt,name=reason,proto3" json:"reason,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *CloseConnectionRequestData) Reset() {
@ -765,7 +765,7 @@ type CloseConnectionRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
CloseRequestData []*CloseConnectionRequestData `protobuf:"bytes,10,rep,name=close_request_data,json=closeRequestData,proto3" json:"close_request_data,omitempty"`
CloseRequestData []*CloseConnectionRequestData `protobuf:"bytes,10,rep,name=close_request_data,json=closeRequestData,proto3" json:"close_request_data,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *CloseConnectionRequest) Reset() {
@ -813,7 +813,7 @@ type CloseConnectionResponseData struct {
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
Status CONNECTIONSTATUS `protobuf:"varint,20,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty"`
Status CONNECTIONSTATUS `protobuf:"varint,20,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *CloseConnectionResponseData) Reset() {
@ -867,7 +867,7 @@ type CloseConnectionResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
CloseResponseData []*CloseConnectionResponseData `protobuf:"bytes,10,rep,name=close_response_data,json=closeResponseData,proto3" json:"close_response_data,omitempty"`
CloseResponseData []*CloseConnectionResponseData `protobuf:"bytes,10,rep,name=close_response_data,json=closeResponseData,proto3" json:"close_response_data,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *CloseConnectionResponse) Reset() {

@ -37,9 +37,10 @@ func newCloudEventsFormatterFilter(source *url.URL, format cloudevents.Format, o
opts := getOpts(opt...)
n := cloudEventsFormatterFilter{
FormatterFilter: &cloudevents.FormatterFilter{
Source: source,
Schema: opts.withSchema,
Format: format,
Source: source,
Schema: opts.withSchema,
Format: format,
SignEventTypes: []string{string(AuditType)},
},
}
@ -66,10 +67,28 @@ func newCloudEventsFormatterFilter(source *url.URL, format cloudevents.Format, o
n.deny = append(n.deny, f)
}
}
defaultDenyFilters, err := defaultCloudEventsDenyFilters()
if err != nil {
return nil, err
}
n.deny = append(n.deny, defaultDenyFilters...)
n.Predicate = newPredicate(n.allow, n.deny)
return &n, nil
}
func defaultCloudEventsDenyFilters() ([]*filter, error) {
const (
op = "event.defaultCloudEventsDenyFilters"
// denyWorkStatusEvents is a default filter for worker to controller API status requests
denyWorkStatusEvents = `"/Data/RequestInfo/Method" contains "ServerCoordinationService/Status"`
)
f, err := newFilter(denyWorkStatusEvents)
if err != nil {
return nil, fmt.Errorf("%s: unable to create deny filter for worker status events '%s': %w", op, denyWorkStatusEvents, err)
}
return []*filter{f}, nil
}
// Rotate supports rotating the filter's wrapper. No options are currently
// supported.
func (f *cloudEventsFormatterFilter) Rotate(w wrapping.Wrapper, _ ...Option) error {

@ -130,10 +130,16 @@ func Test_newCloudEventsFormatterFilter(t *testing.T) {
for _, f := range got.allow {
assert.Contains(tt.wantAllow, f.raw)
}
assert.Len(got.deny, len(tt.wantDeny))
assert.Len(got.deny, len(tt.wantDeny)+1) // +1 since there's always a default deny
defs, err := defaultCloudEventsDenyFilters()
require.NoError(err)
for _, f := range defs {
tt.wantDeny = append(tt.wantDeny, f.raw)
}
for _, f := range got.deny {
assert.Contains(tt.wantDeny, f.raw)
}
assert.Equal([]string{string(AuditType)}, got.SignEventTypes)
})
}
}

@ -66,11 +66,29 @@ func newHclogFormatterFilter(jsonFormat bool, opt ...Option) (*hclogFormatterFil
n.deny = append(n.deny, f)
}
}
defaultDenyFilters, err := defaultHclogEventsDenyFilters()
if err != nil {
return nil, err
}
n.deny = append(n.deny, defaultDenyFilters...)
n.predicate = newPredicate(n.allow, n.deny)
return &n, nil
}
func defaultHclogEventsDenyFilters() ([]*filter, error) {
const (
op = "event.defaultHclogEventsDenyFilters"
// denyWorkStatusEvents is a default filter for worker to controller API status requests
denyWorkStatusEvents = `"/RequestInfo/Method" contains "ServerCoordinationService/Status"`
)
f, err := newFilter(denyWorkStatusEvents)
if err != nil {
return nil, fmt.Errorf("%s: unable to create deny filter for worker status events '%s': %w", op, denyWorkStatusEvents, err)
}
return []*filter{f}, nil
}
// Rotate supports rotating the filter's wrapper. No options are currently
// supported.
func (f *hclogFormatterFilter) Rotate(w wrapping.Wrapper, _ ...Option) error {

@ -387,7 +387,12 @@ func Test_newHclogFormatterFilter(t *testing.T) {
for _, f := range got.allow {
assert.Contains(tt.wantAllow, f.raw)
}
assert.Len(got.deny, len(tt.wantDeny))
assert.Len(got.deny, len(tt.wantDeny)+1) // +1 since there's always a default deny
defs, err := defaultHclogEventsDenyFilters()
require.NoError(err)
for _, f := range defs {
tt.wantDeny = append(tt.wantDeny, f.raw)
}
for _, f := range got.deny {
assert.Contains(tt.wantDeny, f.raw)
}

@ -75,7 +75,7 @@ func Test_testInitStore(t *testing.T) {
testInitStore(t, cleanup, url)
const query = `
select count(*) from information_schema."tables" t where table_name = 'db_test_user';
select count(*) from information_schema."tables" t where table_name = 'boundary_schema_version';
`
db, err := common.SqlOpen("postgres", url)
require.NoError(err)

@ -11,230 +11,234 @@ import "controller/api/resources/scopes/v1/scope.proto";
import "controller/custom_options/v1/options.proto";
message HostSource {
// Output only. The ID of the Host Set.
string id = 10;
// Output only. The ID of the Host Set.
string id = 10;
// Output only. The Host Catalog to which this Host Source belongs.
string host_catalog_id = 20 [json_name="host_catalog_id"];
// Output only. The Host Catalog to which this Host Source belongs.
string host_catalog_id = 20 [json_name = "host_catalog_id"];
}
message HostSet {
// Output only. The ID of the Host Set.
string id = 10;
// Output only. The ID of the Host Set.
string id = 10;
// Output only. The Host Catalog to which this Host Set belongs.
string host_catalog_id = 20 [json_name="host_catalog_id"];
// Output only. The Host Catalog to which this Host Set belongs.
string host_catalog_id = 20 [json_name = "host_catalog_id"];
}
message CredentialSource {
// The ID of the Credential. May be empty if the credential is dynamically generated from a library.
string id = 10;
// The ID of the Credential. May be empty if the credential is dynamically generated from a library.
string id = 10;
// Output only. The name of the Credential source.
string name = 20;
// Output only. The name of the Credential source.
string name = 20;
// Output only. The description of the Credential source.
string description = 30;
// Output only. The description of the Credential source.
string description = 30;
// Output only. The Credential Store to which this Credential source belongs.
string credential_store_id = 40 [json_name="credential_store_id"];
// Output only. The Credential Store to which this Credential source belongs.
string credential_store_id = 40 [json_name = "credential_store_id"];
// Output only. The type of the credential source (e.g. "vault"; not the type of the credential itself).
string type = 60;
// Output only. The type of the credential source (e.g. "vault"; not the type of the credential itself).
string type = 60;
}
message CredentialLibrary {
// The ID of the Credential Library.
string id = 10;
// The ID of the Credential Library.
string id = 10;
// Output only. The name of the Credential Library.
string name = 20;
// Output only. The name of the Credential Library.
string name = 20;
// Output only. The description of the Credential Library.
string description = 30;
// Output only. The description of the Credential Library.
string description = 30;
// Output only. The Credential Store to which this Credential Library belongs.
string credential_store_id = 40 [json_name="credential_store_id"];
// Output only. The Credential Store to which this Credential Library belongs.
string credential_store_id = 40 [json_name = "credential_store_id"];
// Output only. The type of the credential library.
string type = 60;
// Output only. The type of the credential library.
string type = 60;
}
// The actual secret for a session credential.
message SessionSecret {
// Output only. The base64-encoded value representing the raw bytes from the
// credential provider.
string raw = 10;
// Output only. The base64-encoded value representing the raw bytes from the
// credential provider.
string raw = 10;
// Output only. The decoded raw string, if a JSON object.
google.protobuf.Struct decoded = 20;
// Output only. The decoded raw string, if a JSON object.
google.protobuf.Struct decoded = 20;
}
// Credential information for a session.
message SessionCredential {
// Output only. The credential source information.
CredentialSource credential_source = 1;
// Output only. The credential source information.
CredentialSource credential_source = 1;
// Output only. The library which generated this credential. Deprecated: use credential_source instead.
CredentialLibrary credential_library = 10 [deprecated = true];
// Output only. The library which generated this credential. Deprecated: use credential_source instead.
CredentialLibrary credential_library = 10 [deprecated = true];
// Output only. The secret of this credential base64 encoded.
SessionSecret secret = 20;
// Output only. The secret of this credential base64 encoded.
SessionSecret secret = 20;
}
// Target contains all fields related to a Target resource
message Target {
// Output only. The ID of the resource.
string id = 10;
// Output only. The ID of the resource.
string id = 10;
// The Scope of of this resource. This must be defined for creation of this resource, but is otherwise output only.
string scope_id = 20 [json_name="scope_id"];
// The Scope of of this resource. This must be defined for creation of this resource, but is otherwise output only.
string scope_id = 20 [json_name = "scope_id"];
// Output only. Scope information for this resource.
resources.scopes.v1.ScopeInfo scope = 30;
// Required name for identification purposes.
google.protobuf.StringValue name = 40 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this:"name" that: "name"}];
// Output only. Scope information for this resource.
resources.scopes.v1.ScopeInfo scope = 30;
// Optional user-set description for identification purposes.
google.protobuf.StringValue description = 50 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this:"description" that: "description"}];
// Required name for identification purposes.
google.protobuf.StringValue name = 40 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = { this: "name" that: "name" }];
// Output only. The time this resource was created.
google.protobuf.Timestamp created_time = 60 [json_name="created_time"];
// Optional user-set description for identification purposes.
google.protobuf.StringValue description = 50 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = { this: "description" that: "description" }];
// Output only. The time this resource was last updated.
google.protobuf.Timestamp updated_time = 70 [json_name="updated_time"];
// Output only. The time this resource was created.
google.protobuf.Timestamp created_time = 60 [json_name = "created_time"];
// Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.
// The mutation will fail if the version does not match the latest known good version.
uint32 version = 80;
// Output only. The time this resource was last updated.
google.protobuf.Timestamp updated_time = 70 [json_name = "updated_time"];
// The type of the Target.
string type = 90;
// Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.
// The mutation will fail if the version does not match the latest known good version.
uint32 version = 80;
// Output only. The IDs of the Host Sets associated with this Target.
repeated string host_set_ids = 100 [json_name="host_set_ids"];
// The type of the Target.
string type = 90;
// Output only. The Host Sets associated with this Target.
repeated HostSet host_sets = 110 [json_name="host_sets"];
// Output only. The IDs of the Host Sets associated with this Target.
repeated string host_set_ids = 100 [json_name = "host_set_ids"];
// Output only. The IDs of the Host Sources associated with this Target.
repeated string host_source_ids = 420 [json_name="host_source_ids"];
// Output only. The Host Sets associated with this Target.
repeated HostSet host_sets = 110 [json_name = "host_sets"];
// Output only. The Host Sources associated with this Target.
repeated HostSource host_sources = 430 [json_name="host_sources"];
// Output only. The IDs of the Host Sources associated with this Target.
repeated string host_source_ids = 420 [json_name = "host_source_ids"];
// Maximum total lifetime of a created Session, in seconds.
google.protobuf.UInt32Value session_max_seconds = 120 [json_name="session_max_seconds", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this: "session_max_seconds" that: "SessionMaxSeconds"}];
// Output only. The Host Sources associated with this Target.
repeated HostSource host_sources = 430 [json_name = "host_sources"];
// Maximum number of connections allowed in a Session. Unlimited is indicated by the value -1.
google.protobuf.Int32Value session_connection_limit = 130 [json_name="session_connection_limit", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this: "session_connection_limit" that: "SessionConnectionLimit"}];
// Maximum total lifetime of a created Session, in seconds.
google.protobuf.UInt32Value session_max_seconds = 120
[json_name = "session_max_seconds", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = { this: "session_max_seconds" that: "SessionMaxSeconds" }];
// Optional boolean expression to filter the workers that are allowed to satisfy this request.
google.protobuf.StringValue worker_filter = 140 [json_name="worker_filter", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this: "worker_filter" that: "WorkerFilter"}];
// Maximum number of connections allowed in a Session. Unlimited is indicated by the value -1.
google.protobuf.Int32Value session_connection_limit = 130
[json_name = "session_connection_limit", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = { this: "session_connection_limit" that: "SessionConnectionLimit" }];
// Output only. The IDs of the application credential library ids associated with this Target. Deprecated: use application_credential_source_ids instead.
repeated string application_credential_library_ids = 150 [json_name="application_credential_library_ids", deprecated = true];
// Output only. The application credential libraries associated with this Target. Deprecated: use application_credential_sources instead.
repeated CredentialLibrary application_credential_libraries = 180 [json_name="application_credential_libraries", deprecated = true];
// Optional boolean expression to filter the workers that are allowed to satisfy this request.
google.protobuf.StringValue worker_filter = 140
[json_name = "worker_filter", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = { this: "worker_filter" that: "WorkerFilter" }];
// Output only. The IDs of the application credential source ids associated with this Target.
repeated string application_credential_source_ids = 400 [json_name="application_credential_source_ids"];
// Output only. The application credential sources associated with this Target.
repeated CredentialSource application_credential_sources = 410 [json_name="application_credential_sources"];
// Output only. The IDs of the application credential library ids associated with this Target. Deprecated: use application_credential_source_ids instead.
repeated string application_credential_library_ids = 150 [json_name = "application_credential_library_ids", deprecated = true];
// Output only. The application credential libraries associated with this Target. Deprecated: use application_credential_sources instead.
repeated CredentialLibrary application_credential_libraries = 180 [json_name = "application_credential_libraries", deprecated = true];
// Output only. The IDs of the egress credential source ids associated with this Target.
repeated string egress_credential_source_ids = 500 [json_name="egress_credential_source_ids"];
// Output only. The egress credential sources associated with this Target.
repeated CredentialSource egress_credential_sources = 510 [json_name="egress_credential_sources"];
// Output only. The IDs of the application credential source ids associated with this Target.
repeated string application_credential_source_ids = 400 [json_name = "application_credential_source_ids"];
// Output only. The application credential sources associated with this Target.
repeated CredentialSource application_credential_sources = 410 [json_name = "application_credential_sources"];
// The attributes that are applicable for the specific Target.
google.protobuf.Struct attributes = 200 [(custom_options.v1.generate_sdk_option) = true];
// Output only. The IDs of the egress credential source ids associated with this Target.
repeated string egress_credential_source_ids = 500 [json_name = "egress_credential_source_ids"];
// Output only. The egress credential sources associated with this Target.
repeated CredentialSource egress_credential_sources = 510 [json_name = "egress_credential_sources"];
// Output only. The available actions on this resource for this user.
repeated string authorized_actions = 300 [json_name="authorized_actions"];
// The attributes that are applicable for the specific Target.
google.protobuf.Struct attributes = 200 [(custom_options.v1.generate_sdk_option) = true];
// Output only. The available actions on this resource for this user.
repeated string authorized_actions = 300 [json_name = "authorized_actions"];
}
// TcpTargetAttributes contains attributes relevant to Targets of type "tcp"
message TcpTargetAttributes {
// The default TCP port that will be used when connecting to the endpoint unless overridden by a Host Set or Host.
google.protobuf.UInt32Value default_port = 10 [json_name="default_port", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this: "attributes.default_port" that: "DefaultPort"}];
// The default TCP port that will be used when connecting to the endpoint unless overridden by a Host Set or Host.
google.protobuf.UInt32Value default_port = 10
[json_name = "default_port", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = { this: "attributes.default_port" that: "DefaultPort" }];
}
// WorkerInfo contains information about workers, returned in to the client in SessionAuthorization
message WorkerInfo {
// Output only. The address of the worker.
string address = 10;
// Output only. The address of the worker.
string address = 10; // @gotags: `class:"public"`
}
// SessionAuthorizationData contains the fields needed by the proxy command to connect to a worker. It is marshaled inside the SessionAuthorization message.
message SessionAuthorizationData {
// Output only. The ID of the session.
string session_id = 10 [json_name="session_id"];
// Output only. The ID of the session.
string session_id = 10 [json_name = "session_id"]; // @gotags: `class:"public"`
// Output only. The ID of the Target authorizing this session.
string target_id = 20 [json_name="target_id"];
// Output only. The ID of the Target authorizing this session.
string target_id = 20 [json_name = "target_id"]; // @gotags: `class:"public"`
// Output only. Scope information for this the Target that authorized this session.
resources.scopes.v1.ScopeInfo scope = 30;
// Output only. Scope information for this the Target that authorized this session.
resources.scopes.v1.ScopeInfo scope = 30;
// Output only. The time this resource was created.
google.protobuf.Timestamp created_time = 40 [json_name="created_time"];
// Output only. The time this resource was created.
google.protobuf.Timestamp created_time = 40 [json_name = "created_time"]; // @gotags: `class:"public"`
// Output only. Type of the session (e.g. tcp, ssh, etc.).
string type = 80;
// Output only. Type of the session (e.g. tcp, ssh, etc.).
string type = 80; // @gotags: `class:"public"`
// Output only. The connection limit being applied to this session. -1 means unlimited. This is not actually enforced on the client side but it provides for better listener handling by including it.
int32 connection_limit = 90 [json_name="connection_limit"];
// Output only. The connection limit being applied to this session. -1 means unlimited. This is not actually enforced on the client side but it provides for better listener handling by including it.
int32 connection_limit = 90 [json_name = "connection_limit"];
// Output only. The certificate to use when connecting. Raw DER bytes.
bytes certificate = 120;
// Output only. The certificate to use when connecting. Raw DER bytes.
bytes certificate = 120; // @gotags: `class:"secret"`
// Output only. The private key to use when connecting. We are using Ed25519, so this is purely raw bytes, no marshaling.
bytes private_key = 130 [json_name="private_key"];
// Output only. The private key to use when connecting. We are using Ed25519, so this is purely raw bytes, no marshaling.
bytes private_key = 130 [json_name = "private_key"]; // @gotags: `class:"secret"`
// Output only. The host ID...not used for security purposes, but for some special command handling (e.g. ssh host key aliasing).
string host_id = 140;
// Output only. The host ID...not used for security purposes, but for some special command handling (e.g. ssh host key aliasing).
string host_id = 140; // @gotags: `class:"public"`
// Output only. The endpoint, for some special command handling.
string endpoint = 141;
// Output only. The endpoint, for some special command handling.
string endpoint = 141; // @gotags: `class:"public"`
// Output only. Worker information. The first worker in the array should be prioritized.
repeated WorkerInfo worker_info = 150 [json_name="worker_info"];
// Output only. Worker information. The first worker in the array should be prioritized.
repeated WorkerInfo worker_info = 150 [json_name = "worker_info"];
}
// SessionAuthorization contains all fields related to authorization for a Session. It's in the Targets package because it's returned by a Target's authorize action.
message SessionAuthorization {
// Output only. The ID of the Session.
string session_id = 10 [json_name="session_id"];
// Output only. The ID of the Session.
string session_id = 10 [json_name = "session_id"]; // @gotags: `class:"public"`
// Output only. The ID of the Target authorizing this Session.
string target_id = 20 [json_name="target_id"];
// Output only. The ID of the Target authorizing this Session.
string target_id = 20 [json_name = "target_id"]; // @gotags: `class:"public"`
// Output only. Scope information for this resource.
resources.scopes.v1.ScopeInfo scope = 30;
// Output only. Scope information for this resource.
resources.scopes.v1.ScopeInfo scope = 30;
// Output only. The time this resource was created.
google.protobuf.Timestamp created_time = 40 [json_name="created_time"];
// Output only. The time this resource was created.
google.protobuf.Timestamp created_time = 40 [json_name = "created_time"]; // @gotags: `class:"public"`
// Output only. The User for which this Session was authorized.
string user_id = 50 [json_name="user_id"];
// Output only. The User for which this Session was authorized.
string user_id = 50 [json_name = "user_id"]; // @gotags: `class:"public"`
// Output only. The Host Set containing the Host being used for this Session.
string host_set_id = 60 [json_name="host_set_id"];
// Output only. The Host Set containing the Host being used for this Session.
string host_set_id = 60 [json_name = "host_set_id"]; // @gotags: `class:"public"`
// Output only. The Host whose address is being used as the endpoint for this Session.
string host_id = 70 [json_name="host_id"];
// Output only. The Host whose address is being used as the endpoint for this Session.
string host_id = 70 [json_name = "host_id"]; // @gotags: `class:"public"`
// Output only. Type of the Session (e.g. tcp, ssh, etc.).
string type = 80;
// Output only. Type of the Session (e.g. tcp, ssh, etc.).
string type = 80; // @gotags: `class:"public"`
// Output only. The marshaled SessionAuthorizationData message containing all information that the proxy needs.
string authorization_token = 90 [json_name="authorization_token"];
// Output only. The marshaled SessionAuthorizationData message containing all information that the proxy needs.
string authorization_token = 90 [json_name = "authorization_token"]; // @gotags: `class:"private"`
// Output only. The endpoint address that the worker will connect to, useful for setting TLS parameters.
string endpoint = 100;
// Output only. The endpoint address that the worker will connect to, useful for setting TLS parameters.
string endpoint = 100; // @gotags: `class:"public"`
// Output only. The credentials for this session.
repeated SessionCredential credentials = 110 [json_name="credentials"];
// Output only. The credentials for this session.
repeated SessionCredential credentials = 110 [json_name = "credentials"];
}

@ -9,111 +9,111 @@ import "controller/api/resources/targets/v1/target.proto";
import "controller/servers/services/v1/server_coordination_service.proto";
service SessionService {
// GetSession allows a worker to retrieve session information from the
// controller.
rpc LookupSession(LookupSessionRequest) returns (LookupSessionResponse) {}
// ActivateSession allows a worker to activate a session on a controller.
rpc ActivateSession(ActivateSessionRequest) returns (ActivateSessionResponse) {}
// GetSession allows a worker to retrieve session information from the
// controller.
rpc LookupSession(LookupSessionRequest) returns (LookupSessionResponse) {}
// CancelSession allows a worker to request that the controller cancel a session.
rpc CancelSession(CancelSessionRequest) returns (CancelSessionResponse) {}
// ActivateSession allows a worker to activate a session on a controller.
rpc ActivateSession(ActivateSessionRequest) returns (ActivateSessionResponse) {}
// AuthorizeConnection allows a worker to authorize a connection on a controller.
rpc AuthorizeConnection(AuthorizeConnectionRequest) returns (AuthorizeConnectionResponse) {}
// CancelSession allows a worker to request that the controller cancel a session.
rpc CancelSession(CancelSessionRequest) returns (CancelSessionResponse) {}
// ConnectConnection updates a connection to set it to connected
rpc ConnectConnection(ConnectConnectionRequest) returns (ConnectConnectionResponse) {}
// AuthorizeConnection allows a worker to authorize a connection on a controller.
rpc AuthorizeConnection(AuthorizeConnectionRequest) returns (AuthorizeConnectionResponse) {}
// CloseConnections updates a connection to set it to closed
rpc CloseConnection(CloseConnectionRequest) returns (CloseConnectionResponse) {}
// ConnectConnection updates a connection to set it to connected
rpc ConnectConnection(ConnectConnectionRequest) returns (ConnectConnectionResponse) {}
// CloseConnections updates a connection to set it to closed
rpc CloseConnection(CloseConnectionRequest) returns (CloseConnectionResponse) {}
}
message LookupSessionRequest {
// The session ID from the client
string session_id = 10;
// The name of the requesting worker, used for filtering to ensure this
// worker is allowed to handle this session.
string server_id = 20;
// The session ID from the client
string session_id = 10; // @gotags: `class:"public"`
// The name of the requesting worker, used for filtering to ensure this
// worker is allowed to handle this session.
string server_id = 20; // @gotags: `class:"public"`
}
// LookupSessionResponse contains information necessary for a client to
// establish a session.
message LookupSessionResponse {
api.resources.targets.v1.SessionAuthorizationData authorization = 10;
string tofu_token = 20;
uint32 version = 30;
string endpoint = 40;
google.protobuf.Timestamp expiration = 50;
controller.servers.services.v1.SESSIONSTATUS status = 60;
int32 connection_limit = 70;
int32 connections_left = 80;
string host_id = 90;
string host_set_id = 100;
string target_id = 110;
string user_id = 120;
api.resources.targets.v1.SessionAuthorizationData authorization = 10;
string tofu_token = 20; // @gotags: `class:"secret"`
uint32 version = 30; // @gotags: `class:"public"`
string endpoint = 40; // @gotags: `class:"public"`
google.protobuf.Timestamp expiration = 50; // @gotags: `class:"public"`
controller.servers.services.v1.SESSIONSTATUS status = 60; // @gotags: `class:"public"`
int32 connection_limit = 70; // @gotags: `class:"public"`
int32 connections_left = 80; // @gotags: `class:"public"`
string host_id = 90; // @gotags: `class:"public"`
string host_set_id = 100; // @gotags: `class:"public"`
string target_id = 110; // @gotags: `class:"public"`
string user_id = 120; // @gotags: `class:"public"`
}
message ActivateSessionRequest {
string session_id = 10;
string tofu_token = 20;
uint32 version = 30;
string worker_id = 40;
controller.servers.services.v1.SESSIONSTATUS status = 50;
string session_id = 10; // @gotags: `class:"public"`
string tofu_token = 20; // @gotags: `class:"secret"`
uint32 version = 30; // @gotags: `class:"public"`
string worker_id = 40; // @gotags: `class:"public"`
controller.servers.services.v1.SESSIONSTATUS status = 50; // @gotags: `class:"public"`
}
message ActivateSessionResponse {
controller.servers.services.v1.SESSIONSTATUS status = 10;
controller.servers.services.v1.SESSIONSTATUS status = 10; // @gotags: `class:"public"`
}
message CancelSessionRequest {
string session_id = 10;
string session_id = 10; // @gotags: `class:"public"`
}
message CancelSessionResponse {
controller.servers.services.v1.SESSIONSTATUS status = 10;
controller.servers.services.v1.SESSIONSTATUS status = 10; // @gotags: `class:"public"`
}
message AuthorizeConnectionRequest {
string session_id = 10;
string worker_id = 20;
string session_id = 10; // @gotags: `class:"public"`
string worker_id = 20; // @gotags: `class:"public"`
}
message AuthorizeConnectionResponse {
string connection_id = 10;
controller.servers.services.v1.CONNECTIONSTATUS status = 20;
int32 connections_left = 30;
string connection_id = 10; // @gotags: `class:"public"`
controller.servers.services.v1.CONNECTIONSTATUS status = 20; // @gotags: `class:"public"`
int32 connections_left = 30; // @gotags: `class:"public"`
}
message ConnectConnectionRequest {
string connection_id = 10;
string client_tcp_address = 20;
uint32 client_tcp_port = 30;
string endpoint_tcp_address = 40;
uint32 endpoint_tcp_port = 50;
string type = 60;
string connection_id = 10; // @gotags: `class:"public"`
string client_tcp_address = 20; // @gotags: `class:"public"`
uint32 client_tcp_port = 30; // @gotags: `class:"public"`
string endpoint_tcp_address = 40; // @gotags: `class:"public"`
uint32 endpoint_tcp_port = 50; // @gotags: `class:"public"`
string type = 60; // @gotags: `class:"public"`
}
message ConnectConnectionResponse {
controller.servers.services.v1.CONNECTIONSTATUS status = 10;
controller.servers.services.v1.CONNECTIONSTATUS status = 10; // @gotags: `class:"public"`
}
message CloseConnectionRequestData {
string connection_id = 10;
uint64 bytes_up = 20;
uint64 bytes_down = 30;
string reason = 40;
string connection_id = 10; // @gotags: `class:"public"`
uint64 bytes_up = 20; // @gotags: `class:"public"`
uint64 bytes_down = 30; // @gotags: `class:"public"`
string reason = 40; // @gotags: `class:"public"`
}
message CloseConnectionRequest {
repeated CloseConnectionRequestData close_request_data = 10;
repeated CloseConnectionRequestData close_request_data = 10; // @gotags: `class:"public"`
}
message CloseConnectionResponseData {
string connection_id = 10;
controller.servers.services.v1.CONNECTIONSTATUS status = 20;
string connection_id = 10;
controller.servers.services.v1.CONNECTIONSTATUS status = 20; // @gotags: `class:"public"`
}
message CloseConnectionResponse {
repeated CloseConnectionResponseData close_response_data = 10;
repeated CloseConnectionResponseData close_response_data = 10; // @gotags: `class:"public"`
}

@ -22,6 +22,7 @@ import (
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/accounts"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/authtokens"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/managed_groups"
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/resource"
"github.com/hashicorp/boundary/internal/types/scope"
@ -60,7 +61,8 @@ var (
}
collectionTypeMap = map[resource.Type]action.ActionSet{
resource.Account: accounts.CollectionActions,
resource.Account: accounts.CollectionActions,
resource.ManagedGroup: managed_groups.CollectionActions,
}
)

@ -64,6 +64,12 @@ var authorizedCollectionActions = map[string]*structpb.ListValue{
structpb.NewStringValue("list"),
},
},
"managed-groups": {
Values: []*structpb.Value{
structpb.NewStringValue("create"),
structpb.NewStringValue("list"),
},
},
}
func TestGet(t *testing.T) {

@ -13,6 +13,7 @@ import (
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/observability/event"
"github.com/hashicorp/boundary/internal/requests"
commonSrv "github.com/hashicorp/boundary/internal/servers/common"
"github.com/hashicorp/boundary/internal/servers/controller/auth"
"github.com/hashicorp/boundary/internal/servers/controller/common"
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
@ -268,3 +269,39 @@ func auditResponseInterceptor(
return resp, err
}
}
func workerRequestInfoInterceptor(ctx context.Context, eventer *event.Eventer) (grpc.UnaryServerInterceptor, error) {
const op = "worker.requestInfoInterceptor"
if eventer == nil {
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing eventer")
}
return func(interceptorCtx context.Context,
req interface{},
srvInfo *grpc.UnaryServerInfo,
handler grpc.UnaryHandler) (interface{}, error) {
var err error
id, err := event.NewId(event.IdPrefix)
if err != nil {
event.WriteError(interceptorCtx, op, err, event.WithInfoMsg("unable to create id for event", "method", srvInfo.FullMethod))
return nil, status.Errorf(codes.Internal, "Error creating id for event: %v", err)
}
info := &event.RequestInfo{
EventId: id,
Id: commonSrv.GeneratedTraceId(interceptorCtx),
Method: srvInfo.FullMethod,
}
interceptorCtx, err = event.NewRequestInfoContext(interceptorCtx, info)
if err != nil {
event.WriteError(interceptorCtx, op, err, event.WithInfoMsg("unable to create context with request info", "method", srvInfo.FullMethod))
return nil, status.Errorf(codes.Internal, "Error creating context with request info: %v", err)
}
interceptorCtx, err = event.NewEventerContext(interceptorCtx, eventer)
if err != nil {
event.WriteError(interceptorCtx, op, err, event.WithInfoMsg("unable to create context with eventer", "method", srvInfo.FullMethod))
return nil, status.Errorf(codes.Internal, "Error creating context with eventer: %v", err)
}
// call the handler...
return handler(interceptorCtx, req)
}, nil
}

@ -464,6 +464,97 @@ func Test_statusCodeInterceptor(t *testing.T) {
}
}
func Test_workerRequestInfoInterceptor(t *testing.T) {
factoryCtx := context.Background()
requestCtx := context.Background()
returnCtxHandler := func(ctx context.Context, req interface{}) (interface{}, error) {
return ctx, nil
}
c := event.TestEventerConfig(t, "Test_requestCtxInterceptor", event.TestWithAuditSink(t), event.TestWithObservationSink(t))
testLock := &sync.Mutex{}
testLogger := hclog.New(&hclog.LoggerOptions{
Mutex: testLock,
Name: "test",
})
testEventer, err := event.NewEventer(testLogger, testLock, "Test_requestCtxInterceptor", c.EventerConfig)
require.NoError(t, err)
tests := []struct {
name string
requestCtx context.Context
eventer *event.Eventer
wantFactoryErr bool
wantFactoryErrMatch *errors.Template
wantFactoryErrContains string
wantRequestErr bool
wantRequestErrMatch *errors.Template
wantRequestErrContains string
}{
{
name: "missing-eventer",
requestCtx: requestCtx,
wantFactoryErr: true,
wantFactoryErrMatch: errors.T(errors.InvalidParameter),
wantFactoryErrContains: "missing eventer",
},
{
name: "valid",
requestCtx: requestCtx,
eventer: testEventer,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
interceptor, err := workerRequestInfoInterceptor(factoryCtx, tt.eventer)
if tt.wantFactoryErr {
require.Error(err)
assert.Nil(interceptor)
if tt.wantFactoryErrMatch != nil {
assert.Truef(errors.Match(tt.wantFactoryErrMatch, err), "want err code: %q got: %q", tt.wantFactoryErrMatch.Code, err)
}
if tt.wantFactoryErrContains != "" {
assert.Contains(err.Error(), tt.wantFactoryErrContains)
}
return
}
require.NoError(err)
assert.NotNil(interceptor)
info := &grpc.UnaryServerInfo{
FullMethod: "FakeMethod",
}
retCtx, err := interceptor(tt.requestCtx, nil, info, returnCtxHandler)
if tt.wantRequestErr {
require.Error(err)
assert.Nil(retCtx)
if tt.wantRequestErrMatch != nil {
assert.Truef(errors.Match(tt.wantRequestErrMatch, err), "want err code: %q got: %q", tt.wantRequestErrMatch.Code, err)
}
if tt.wantRequestErrContains != "" {
assert.Contains(err.Error(), tt.wantRequestErrContains)
}
return
}
require.NoError(err)
requestInfo, found := event.RequestInfoFromContext(retCtx.(context.Context))
require.True(found)
assert.NotNil(requestInfo)
assert.NotEmpty(requestInfo.Id)
assert.NotEmpty(requestInfo.EventId)
assert.Equal("FakeMethod", requestInfo.Method)
eventer, found := event.EventerFromContext(retCtx.(context.Context))
require.True(found)
assert.NotNil(eventer)
})
}
}
type testGreeter struct {
interceptor.UnimplementedGreeterServiceServer
}

@ -12,6 +12,7 @@ import (
"sync"
"time"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/cmd/base"
pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services"
@ -123,9 +124,20 @@ func (c *Controller) startListeners(ctx context.Context) error {
return fmt.Errorf("error getting sub-listener for worker proto: %w", err)
}
workerReqInterceptor, err := workerRequestInfoInterceptor(ctx, c.conf.Eventer)
if err != nil {
return fmt.Errorf("error getting sub-listener for worker proto: %w", err)
}
workerServer := grpc.NewServer(
grpc.MaxRecvMsgSize(math.MaxInt32),
grpc.MaxSendMsgSize(math.MaxInt32),
grpc.UnaryInterceptor(
grpc_middleware.ChainUnaryServer(
workerReqInterceptor,
auditRequestInterceptor(ctx), // before we get started, audit the request
auditResponseInterceptor(ctx), // as we finish, audit the response
),
),
)
workerService := workers.NewWorkerServiceServer(c.ServersRepoFn, c.SessionRepoFn, c.workerStatusUpdateTimes, c.kms)
pbs.RegisterServerCoordinationServiceServer(workerServer, workerService)

@ -3,7 +3,7 @@ module github.com/hashicorp/boundary/sdk
go 1.17
require (
github.com/hashicorp/eventlogger v0.1.1-0.20211104100552-e1e801e50144
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c
github.com/hashicorp/eventlogger/filters/encrypt v0.1.6-0.20211027211326-5db60a48f239
github.com/hashicorp/go-hclog v0.16.2
github.com/hashicorp/go-kms-wrapping v0.6.6

@ -242,8 +242,8 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/eventlogger v0.1.0/go.mod h1:a3IXf1aEJfpCPzseTOrwKj4fVW/Qn3oEmpQeaIznzH0=
github.com/hashicorp/eventlogger v0.1.1-0.20211104100552-e1e801e50144 h1:PCl0HtlVnIIloIozAKvjICu6K4IghKXAKNny3R3b2nI=
github.com/hashicorp/eventlogger v0.1.1-0.20211104100552-e1e801e50144/go.mod h1:a3IXf1aEJfpCPzseTOrwKj4fVW/Qn3oEmpQeaIznzH0=
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c h1:u1Zq+LfTXaagmJCHK3XH/fi7pk7oRY933VjGNG7/Ynw=
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c/go.mod h1:NaXU8p/pl5a2RX/N0/yncinT3Iw5CLkbF4JRxAVnk3c=
github.com/hashicorp/eventlogger/filters/encrypt v0.1.6-0.20211027211326-5db60a48f239 h1:Yh9tY0lige+y0trmjQeT9NRDo6+YvtNAzbmUNOsIUzI=
github.com/hashicorp/eventlogger/filters/encrypt v0.1.6-0.20211027211326-5db60a48f239/go.mod h1:8rcez7Kw1zanB0/074qnOuGu7zxmNh9Xr2ZI+K4xVIA=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=

@ -755,7 +755,7 @@ type WorkerInfo struct {
unknownFields protoimpl.UnknownFields
// Output only. The address of the worker.
Address string `protobuf:"bytes,10,opt,name=address,proto3" json:"address,omitempty"`
Address string `protobuf:"bytes,10,opt,name=address,proto3" json:"address,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *WorkerInfo) Reset() {
@ -804,25 +804,25 @@ type SessionAuthorizationData struct {
unknownFields protoimpl.UnknownFields
// Output only. The ID of the session.
SessionId string `protobuf:"bytes,10,opt,name=session_id,proto3" json:"session_id,omitempty"`
SessionId string `protobuf:"bytes,10,opt,name=session_id,proto3" json:"session_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The ID of the Target authorizing this session.
TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty"`
TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. Scope information for this the Target that authorized this session.
Scope *scopes.ScopeInfo `protobuf:"bytes,30,opt,name=scope,proto3" json:"scope,omitempty"`
// Output only. The time this resource was created.
CreatedTime *timestamppb.Timestamp `protobuf:"bytes,40,opt,name=created_time,proto3" json:"created_time,omitempty"`
CreatedTime *timestamppb.Timestamp `protobuf:"bytes,40,opt,name=created_time,proto3" json:"created_time,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. Type of the session (e.g. tcp, ssh, etc.).
Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty"`
Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The connection limit being applied to this session. -1 means unlimited. This is not actually enforced on the client side but it provides for better listener handling by including it.
ConnectionLimit int32 `protobuf:"varint,90,opt,name=connection_limit,proto3" json:"connection_limit,omitempty"`
// Output only. The certificate to use when connecting. Raw DER bytes.
Certificate []byte `protobuf:"bytes,120,opt,name=certificate,proto3" json:"certificate,omitempty"`
Certificate []byte `protobuf:"bytes,120,opt,name=certificate,proto3" json:"certificate,omitempty" class:"secret"` // @gotags: `class:"secret"`
// Output only. The private key to use when connecting. We are using Ed25519, so this is purely raw bytes, no marshaling.
PrivateKey []byte `protobuf:"bytes,130,opt,name=private_key,proto3" json:"private_key,omitempty"`
PrivateKey []byte `protobuf:"bytes,130,opt,name=private_key,proto3" json:"private_key,omitempty" class:"secret"` // @gotags: `class:"secret"`
// Output only. The host ID...not used for security purposes, but for some special command handling (e.g. ssh host key aliasing).
HostId string `protobuf:"bytes,140,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty"`
HostId string `protobuf:"bytes,140,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The endpoint, for some special command handling.
Endpoint string `protobuf:"bytes,141,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
Endpoint string `protobuf:"bytes,141,opt,name=endpoint,proto3" json:"endpoint,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. Worker information. The first worker in the array should be prioritized.
WorkerInfo []*WorkerInfo `protobuf:"bytes,150,rep,name=worker_info,proto3" json:"worker_info,omitempty"`
}
@ -943,25 +943,25 @@ type SessionAuthorization struct {
unknownFields protoimpl.UnknownFields
// Output only. The ID of the Session.
SessionId string `protobuf:"bytes,10,opt,name=session_id,proto3" json:"session_id,omitempty"`
SessionId string `protobuf:"bytes,10,opt,name=session_id,proto3" json:"session_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The ID of the Target authorizing this Session.
TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty"`
TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. Scope information for this resource.
Scope *scopes.ScopeInfo `protobuf:"bytes,30,opt,name=scope,proto3" json:"scope,omitempty"`
// Output only. The time this resource was created.
CreatedTime *timestamppb.Timestamp `protobuf:"bytes,40,opt,name=created_time,proto3" json:"created_time,omitempty"`
CreatedTime *timestamppb.Timestamp `protobuf:"bytes,40,opt,name=created_time,proto3" json:"created_time,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The User for which this Session was authorized.
UserId string `protobuf:"bytes,50,opt,name=user_id,proto3" json:"user_id,omitempty"`
UserId string `protobuf:"bytes,50,opt,name=user_id,proto3" json:"user_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The Host Set containing the Host being used for this Session.
HostSetId string `protobuf:"bytes,60,opt,name=host_set_id,proto3" json:"host_set_id,omitempty"`
HostSetId string `protobuf:"bytes,60,opt,name=host_set_id,proto3" json:"host_set_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The Host whose address is being used as the endpoint for this Session.
HostId string `protobuf:"bytes,70,opt,name=host_id,proto3" json:"host_id,omitempty"`
HostId string `protobuf:"bytes,70,opt,name=host_id,proto3" json:"host_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. Type of the Session (e.g. tcp, ssh, etc.).
Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty"`
Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The marshaled SessionAuthorizationData message containing all information that the proxy needs.
AuthorizationToken string `protobuf:"bytes,90,opt,name=authorization_token,proto3" json:"authorization_token,omitempty"`
AuthorizationToken string `protobuf:"bytes,90,opt,name=authorization_token,proto3" json:"authorization_token,omitempty" class:"private"` // @gotags: `class:"private"`
// Output only. The endpoint address that the worker will connect to, useful for setting TLS parameters.
Endpoint string `protobuf:"bytes,100,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
Endpoint string `protobuf:"bytes,100,opt,name=endpoint,proto3" json:"endpoint,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The credentials for this session.
Credentials []*SessionCredential `protobuf:"bytes,110,rep,name=credentials,proto3" json:"credentials,omitempty"`
}

@ -19,7 +19,7 @@ Start by configuring a `Host` entry in `.ssh/ssh_config` for `localhost`:
```bash
Host ttcp_*
ProxyCommand sh -c "boundary connect -target-id %h -exec nc -- {{boundary.ip}} {{boundary.port}}"
ProxyCommand sh -c "boundary connect -target-id %n -exec nc -- {{boundary.ip}} {{boundary.port}}"
```
The `ProxyCommand` tells the SSH client to invoke `boundary connect`. We are passing the `-exec nc` flag to

@ -119,6 +119,11 @@ module.exports = [
destination: '/docs/concepts/domain-model/credential-libraries',
permanent: false,
},
{
source: '/help/admin-ui/managed-groups',
destination: '/docs/concepts/domain-model/managed-groups',
permanent: false,
},
////////////////////////////////////////////
// Adding sub-resources to existing resource

Loading…
Cancel
Save