feature (workers): Add audit events for worker requests (#1681)
* feature (audit events): Add interceptor for auditing worker requests * feature (events): Add default deny filter for worker status events * feature (worker audit events): Add tags to SessionService req/resp
This commit is contained in:
12 files changed
+448
-257
No files matched your search
@@ -142,7 +142,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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -67,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,7 +130,12 @@ 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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user