Merge branch 'main' into plugin-hostcatalogs
# Conflicts: # go.mod # sdk/go.mod
This commit is contained in:
commit
884e1f2d18
27 files changed
+811
-272
No files matched your search
@@ -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 := ×tamp.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)
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
Reference in new issue
Block a user