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:
Jim authored and GitHub committed 2021-11-09 11:43:41 -05:00
1 parent aa8f216f4f
commit 048fceaf54
12 files changed
+448 -257

No files matched your search

+2 -1
View File
@@ -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
View File
@@ -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"`
}