From e937b0ea277305f23fa546519bb01ddf1f06df75 Mon Sep 17 00:00:00 2001 From: Todd Knight Date: Sun, 20 Sep 2020 17:22:57 -0700 Subject: [PATCH] Sessions Read/List/Cancel API and SDK (#369) --- api/internal/genapi/input.go | 20 + api/sessions/cancel.go | 75 ++ api/sessions/option.gen.go | 46 ++ api/sessions/session.gen.go | 200 +++++ api/sessions/state.gen.go | 12 + api/sessions/workers.gen.go | 6 + internal/gen/controller.swagger.json | 238 ++++++ .../api/resources/sessions/session.pb.go | 383 ++++++--- .../api/services/session_service.pb.go | 740 ++++++++++++++++++ .../api/services/session_service.pb.gw.go | 410 ++++++++++ .../api/resources/sessions/v1/session.proto | 107 ++- .../api/services/v1/session_service.proto | 79 ++ internal/servers/controller/common/common.go | 2 +- internal/servers/controller/controller.go | 2 +- internal/servers/controller/handler.go | 8 + internal/servers/controller/handler_test.go | 7 +- .../handlers/sessions/session_service.go | 253 ++++++ .../handlers/sessions/session_service_test.go | 369 +++++++++ internal/session/session.go | 7 + internal/session/testing.go | 14 + internal/types/action/action.go | 3 + internal/types/resource/resource.go | 1 + 22 files changed, 2852 insertions(+), 130 deletions(-) create mode 100644 api/sessions/cancel.go create mode 100644 api/sessions/option.gen.go create mode 100644 api/sessions/session.gen.go create mode 100644 api/sessions/state.gen.go create mode 100644 api/sessions/workers.gen.go create mode 100644 internal/gen/controller/api/services/session_service.pb.go create mode 100644 internal/gen/controller/api/services/session_service.pb.gw.go create mode 100644 internal/proto/local/controller/api/services/v1/session_service.proto create mode 100644 internal/servers/controller/handlers/sessions/session_service.go create mode 100644 internal/servers/controller/handlers/sessions/session_service_test.go diff --git a/api/internal/genapi/input.go b/api/internal/genapi/input.go index 93ec85b19..9c0e6f18f 100644 --- a/api/internal/genapi/input.go +++ b/api/internal/genapi/input.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/boundary/internal/gen/controller/api/resources/hostsets" "github.com/hashicorp/boundary/internal/gen/controller/api/resources/roles" "github.com/hashicorp/boundary/internal/gen/controller/api/resources/scopes" + "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" "github.com/hashicorp/boundary/internal/gen/controller/api/resources/users" "google.golang.org/protobuf/proto" @@ -356,6 +357,25 @@ var inputStructs = []*structInfo{ outFile: "targets/tcp_target_attributes.gen.go", subtypeName: "TcpTarget", }, + { + inProto: &sessions.Session{}, + outFile: "sessions/session.gen.go", + templates: []*template.Template{ + clientTemplate, + readTemplate, + listTemplate, + }, + pathArgs: []string{"session"}, + createResponseTypes: true, + }, + { + inProto: &sessions.SessionState{}, + outFile: "sessions/state.gen.go", + }, + { + inProto: &sessions.WorkerInfo{}, + outFile: "sessions/workers.gen.go", + }, { inProto: &targets.SessionAuthorization{}, outFile: "targets/session_authorization.gen.go", diff --git a/api/sessions/cancel.go b/api/sessions/cancel.go new file mode 100644 index 000000000..be803dbe2 --- /dev/null +++ b/api/sessions/cancel.go @@ -0,0 +1,75 @@ +package sessions + +import ( + "context" + "errors" + "fmt" + "net/url" + + "github.com/hashicorp/boundary/api" + "github.com/kr/pretty" +) + +func (c *Client) Cancel(ctx context.Context, sessionId string, version uint32, opt ...Option) (*SessionUpdateResult, *api.Error, error) { + if sessionId == "" { + return nil, nil, fmt.Errorf("empty sessionId value passed into Cancel request") + } + if c.client == nil { + return nil, nil, errors.New("nil client") + } + + opts, apiOpts := getOpts(opt...) + + if version == 0 { + if !opts.withAutomaticVersioning { + return nil, nil, errors.New("zero version number passed into Cancel request") + } + existingSession, existingApiErr, existingErr := c.Read(ctx, sessionId, opt...) + if existingErr != nil { + return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr) + } + if existingApiErr != nil { + return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr)) + } + if existingSession == nil { + return nil, nil, errors.New("nil resource response found when performing initial check-and-set read") + } + if existingSession.Item == nil { + return nil, nil, errors.New("nil resource found when performing initial check-and-set read") + } + version = existingSession.Item.Version + } + + opts.postMap["version"] = version + + req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("sessions/%s:cancel", sessionId), opts.postMap, apiOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error creating Cancel request: %w", err) + } + + if len(opts.queryMap) > 0 { + q := url.Values{} + for k, v := range opts.queryMap { + q.Add(k, v) + } + req.URL.RawQuery = q.Encode() + } + + resp, err := c.client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during Cancel call: %w", err) + } + + target := new(SessionUpdateResult) + target.Item = new(Session) + apiErr, err := resp.Decode(target.Item) + if err != nil { + return nil, nil, fmt.Errorf("error decoding Cancel response: %w", err) + } + if apiErr != nil { + return nil, apiErr, nil + } + target.responseBody = resp.Body + target.responseMap = resp.Map + return target, apiErr, nil +} diff --git a/api/sessions/option.gen.go b/api/sessions/option.gen.go new file mode 100644 index 000000000..f3716ca53 --- /dev/null +++ b/api/sessions/option.gen.go @@ -0,0 +1,46 @@ +package sessions + +import ( + "github.com/hashicorp/boundary/api" +) + +// Option is a func that sets optional attributes for a call. This does not need +// to be used directly, but instead option arguments are built from the +// functions in this package. WithX options set a value to that given in the +// argument; DefaultX options indicate that the value should be set to its +// default. When an API call is made options are processed in ther order they +// appear in the function call, so for a given argument X, a succession of WithX +// or DefaultX calls will result in the last call taking effect. +type Option func(*options) + +type options struct { + postMap map[string]interface{} + queryMap map[string]string + withAutomaticVersioning bool +} + +func getDefaultOptions() options { + return options{ + postMap: make(map[string]interface{}), + queryMap: make(map[string]string), + } +} + +func getOpts(opt ...Option) (options, []api.Option) { + opts := getDefaultOptions() + for _, o := range opt { + o(&opts) + } + var apiOpts []api.Option + return opts, apiOpts +} + +// If set, and if the version is zero during an update, the API will perform a +// fetch to get the current version of the resource and populate it during the +// update call. This is convenient but opens up the possibility for subtle +// order-of-modification issues, so use carefully. +func WithAutomaticVersioning(enable bool) Option { + return func(o *options) { + o.withAutomaticVersioning = enable + } +} diff --git a/api/sessions/session.gen.go b/api/sessions/session.gen.go new file mode 100644 index 000000000..b47fb8146 --- /dev/null +++ b/api/sessions/session.gen.go @@ -0,0 +1,200 @@ +// Code generated by "make api"; DO NOT EDIT. +package sessions + +import ( + "bytes" + "context" + "fmt" + "net/url" + "time" + + "github.com/hashicorp/boundary/api" + "github.com/hashicorp/boundary/api/scopes" +) + +type Session struct { + Id string `json:"id,omitempty"` + TargetId string `json:"target_id,omitempty"` + Scope *scopes.ScopeInfo `json:"scope,omitempty"` + CreatedTime time.Time `json:"created_time,omitempty"` + UpdatedTime time.Time `json:"updated_time,omitempty"` + ExpirationTime time.Time `json:"expiration_time,omitempty"` + Version uint32 `json:"version,omitempty"` + Type string `json:"type,omitempty"` + AuthTokenId string `json:"auth_token_id,omitempty"` + UserId string `json:"user_id,omitempty"` + HostSetId string `json:"host_set_id,omitempty"` + HostId string `json:"host_id,omitempty"` + ScopeId string `json:"scope_id,omitempty"` + Endpoint string `json:"endpoint,omitempty"` + States []*SessionState `json:"states,omitempty"` + Status string `json:"status,omitempty"` + WorkerInfo []*WorkerInfo `json:"worker_info,omitempty"` + Certificate []byte `json:"certificate,omitempty"` + PrivateKey []byte `json:"private_key,omitempty"` + + responseBody *bytes.Buffer + responseMap map[string]interface{} +} + +func (n Session) ResponseBody() *bytes.Buffer { + return n.responseBody +} + +func (n Session) ResponseMap() map[string]interface{} { + return n.responseMap +} + +type SessionReadResult struct { + Item *Session + responseBody *bytes.Buffer + responseMap map[string]interface{} +} + +func (n SessionReadResult) GetItem() interface{} { + return n.Item +} + +func (n SessionReadResult) GetResponseBody() *bytes.Buffer { + return n.responseBody +} + +func (n SessionReadResult) GetResponseMap() map[string]interface{} { + return n.responseMap +} + +type SessionCreateResult = SessionReadResult +type SessionUpdateResult = SessionReadResult + +type SessionDeleteResult struct { + responseBody *bytes.Buffer + responseMap map[string]interface{} +} + +func (n SessionDeleteResult) GetResponseBody() *bytes.Buffer { + return n.responseBody +} + +func (n SessionDeleteResult) GetResponseMap() map[string]interface{} { + return n.responseMap +} + +type SessionListResult struct { + Items []*Session + responseBody *bytes.Buffer + responseMap map[string]interface{} +} + +func (n SessionListResult) GetItems() interface{} { + return n.Items +} + +func (n SessionListResult) GetResponseBody() *bytes.Buffer { + return n.responseBody +} + +func (n SessionListResult) GetResponseMap() map[string]interface{} { + return n.responseMap +} + +// Client is a client for this collection +type Client struct { + client *api.Client +} + +// Creates a new client for this collection. The submitted API client is cloned; +// modifications to it after generating this client will not have effect. If you +// need to make changes to the underlying API client, use ApiClient() to access +// it. +func NewClient(c *api.Client) *Client { + return &Client{client: c.Clone()} +} + +// ApiClient returns the underlying API client +func (c *Client) ApiClient() *api.Client { + return c.client +} + +func (c *Client) Read(ctx context.Context, sessionId string, opt ...Option) (*SessionReadResult, *api.Error, error) { + if sessionId == "" { + return nil, nil, fmt.Errorf("empty sessionId value passed into Read request") + } + if c.client == nil { + return nil, nil, fmt.Errorf("nil client") + } + + opts, apiOpts := getOpts(opt...) + + req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("sessions/%s", sessionId), nil, apiOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error creating Read request: %w", err) + } + + if len(opts.queryMap) > 0 { + q := url.Values{} + for k, v := range opts.queryMap { + q.Add(k, v) + } + req.URL.RawQuery = q.Encode() + } + + resp, err := c.client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during Read call: %w", err) + } + + target := new(SessionReadResult) + target.Item = new(Session) + apiErr, err := resp.Decode(target.Item) + if err != nil { + return nil, nil, fmt.Errorf("error decoding Read response: %w", err) + } + if apiErr != nil { + return nil, apiErr, nil + } + target.responseBody = resp.Body + target.responseMap = resp.Map + return target, apiErr, nil +} + +func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*SessionListResult, *api.Error, error) { + if scopeId == "" { + return nil, nil, fmt.Errorf("empty scopeId value passed into List request") + } + if c.client == nil { + return nil, nil, fmt.Errorf("nil client") + } + + opts, apiOpts := getOpts(opt...) + opts.queryMap["scope_id"] = scopeId + + req, err := c.client.NewRequest(ctx, "GET", "sessions", nil, apiOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error creating List request: %w", err) + } + + if len(opts.queryMap) > 0 { + q := url.Values{} + for k, v := range opts.queryMap { + q.Add(k, v) + } + req.URL.RawQuery = q.Encode() + } + + resp, err := c.client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during List call: %w", err) + } + + target := new(SessionListResult) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding List response: %w", err) + } + if apiErr != nil { + return nil, apiErr, nil + } + target.responseBody = resp.Body + target.responseMap = resp.Map + return target, apiErr, nil +} diff --git a/api/sessions/state.gen.go b/api/sessions/state.gen.go new file mode 100644 index 000000000..c9810948c --- /dev/null +++ b/api/sessions/state.gen.go @@ -0,0 +1,12 @@ +// Code generated by "make api"; DO NOT EDIT. +package sessions + +import ( + "time" +) + +type SessionState struct { + Status string `json:"status,omitempty"` + StartTime time.Time `json:"start_time,omitempty"` + EndTime time.Time `json:"end_time,omitempty"` +} diff --git a/api/sessions/workers.gen.go b/api/sessions/workers.gen.go new file mode 100644 index 000000000..113654da8 --- /dev/null +++ b/api/sessions/workers.gen.go @@ -0,0 +1,6 @@ +// Code generated by "make api"; DO NOT EDIT. +package sessions + +type WorkerInfo struct { + Address string `json:"address,omitempty"` +} diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json index 19d5ffc89..1895183ec 100644 --- a/internal/gen/controller.swagger.json +++ b/internal/gen/controller.swagger.json @@ -1815,6 +1815,93 @@ ] } }, + "/v1/sessions": { + "get": { + "summary": "Lists all Sessions", + "operationId": "SessionService_ListSessions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/controller.api.services.v1.ListSessionsResponse" + } + } + }, + "parameters": [ + { + "name": "scope_id", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "view", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "controller.api.services.v1.SessionService" + ] + } + }, + "/v1/sessions/{id}": { + "get": { + "summary": "Gets a single Session", + "operationId": "SessionService_GetSession", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.Session" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "view", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "controller.api.services.v1.SessionService" + ] + } + }, + "/v1/sessions/{id}:cancel": { + "post": { + "summary": "Cancels a Session", + "operationId": "SessionService_CancelSession", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.Session" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "controller.api.services.v1.SessionService" + ] + } + }, "/v1/targets": { "get": { "summary": "Lists all Targets", @@ -2897,6 +2984,130 @@ } } }, + "controller.api.resources.sessions.v1.Session": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the resource\nOutput only.", + "readOnly": true + }, + "target_id": { + "type": "string", + "description": "The id of the parent of this resource. This must be defined for creation\nof this resource, but is otherwise read only." + }, + "scope": { + "$ref": "#/definitions/controller.api.resources.scopes.v1.ScopeInfo", + "description": "Scope information for this resource\nOutput only.", + "readOnly": true + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "The time this resource was created\nOutput only.", + "readOnly": true + }, + "updated_time": { + "type": "string", + "format": "date-time", + "description": "The time this resource was last updated.\nOutput only.", + "readOnly": true + }, + "expiration_time": { + "type": "string", + "format": "date-time", + "title": "After this time the connection will be expired, e.g. forcefully terminated" + }, + "version": { + "type": "integer", + "format": "int64", + "description": "The version can be used in subsequent write requests to ensure this\nresource has not changed and to fail the write if it has." + }, + "type": { + "type": "string", + "title": "Type of the session (e.g. tcp, ssh, etc.)" + }, + "auth_token_id": { + "type": "string", + "description": "The id of the token used to authenticate." + }, + "user_id": { + "type": "string", + "title": "The ID of the user that requested the session" + }, + "host_set_id": { + "type": "string" + }, + "host_id": { + "type": "string" + }, + "scope_id": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "states": { + "type": "array", + "items": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.SessionState" + }, + "description": "The states of this session in descending from the current state to the\nfirst." + }, + "status": { + "type": "string", + "description": "The name of the current status of this session." + }, + "worker_info": { + "type": "array", + "items": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.WorkerInfo" + }, + "description": "Worker information. The first worker in the slice should be prioritized." + }, + "certificate": { + "type": "string", + "format": "byte", + "description": "Deprecated, to be moved to another proto by another PR:\nThe certificate to use when connecting (or if using custom certs, to\nserve as the \"login\"). Raw DER bytes." + }, + "private_key": { + "type": "string", + "format": "byte", + "description": "The private key to use when connecting (or if using custom certs, to pass\nas the \"password\")." + } + }, + "title": "Session contains all fields related to a Session resource" + }, + "controller.api.resources.sessions.v1.SessionState": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "This is the status of the session. For example \"pending\", \"active\",\n\"canceling\", \"terminated\"." + }, + "start_time": { + "type": "string", + "format": "date-time", + "description": "The time the session entered this state.\nOutput only.", + "readOnly": true + }, + "end_time": { + "type": "string", + "format": "date-time", + "description": "The time the session stopped being in this state.\nOutput only.", + "readOnly": true + } + } + }, + "controller.api.resources.sessions.v1.WorkerInfo": { + "type": "object", + "properties": { + "address": { + "type": "string", + "title": "The address of the worker" + } + } + }, "controller.api.resources.targets.v1.HostSet": { "type": "object", "properties": { @@ -3250,6 +3461,14 @@ } } }, + "controller.api.services.v1.CancelSessionResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.Session" + } + } + }, "controller.api.services.v1.ChangePasswordRequest": { "type": "object", "properties": { @@ -3491,6 +3710,14 @@ } } }, + "controller.api.services.v1.GetSessionResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.Session" + } + } + }, "controller.api.services.v1.GetTargetResponse": { "type": "object", "properties": { @@ -3606,6 +3833,17 @@ } } }, + "controller.api.services.v1.ListSessionsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/controller.api.resources.sessions.v1.Session" + } + } + } + }, "controller.api.services.v1.ListTargetsResponse": { "type": "object", "properties": { diff --git a/internal/gen/controller/api/resources/sessions/session.pb.go b/internal/gen/controller/api/resources/sessions/session.pb.go index 4c19eaa08..c38a3f015 100644 --- a/internal/gen/controller/api/resources/sessions/session.pb.go +++ b/internal/gen/controller/api/resources/sessions/session.pb.go @@ -12,7 +12,7 @@ import ( timestamp "github.com/golang/protobuf/ptypes/timestamp" _ "github.com/golang/protobuf/ptypes/wrappers" scopes "github.com/hashicorp/boundary/internal/gen/controller/api/resources/scopes" - targets "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" + _ "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" _ "github.com/hashicorp/boundary/internal/gen/controller/protooptions" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -31,6 +31,123 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 +type WorkerInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The address of the worker + Address string `protobuf:"bytes,10,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *WorkerInfo) Reset() { + *x = WorkerInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkerInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkerInfo) ProtoMessage() {} + +func (x *WorkerInfo) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkerInfo.ProtoReflect.Descriptor instead. +func (*WorkerInfo) Descriptor() ([]byte, []int) { + return file_controller_api_resources_sessions_v1_session_proto_rawDescGZIP(), []int{0} +} + +func (x *WorkerInfo) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type SessionState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // This is the status of the session. For example "pending", "active", + // "canceling", "terminated". + Status string `protobuf:"bytes,10,opt,name=status,proto3" json:"status,omitempty"` + // The time the session entered this state. + // Output only. + StartTime *timestamp.Timestamp `protobuf:"bytes,20,opt,name=start_time,proto3" json:"start_time,omitempty"` + // The time the session stopped being in this state. + // Output only. + EndTime *timestamp.Timestamp `protobuf:"bytes,30,opt,name=end_time,proto3" json:"end_time,omitempty"` +} + +func (x *SessionState) Reset() { + *x = SessionState{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionState) ProtoMessage() {} + +func (x *SessionState) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionState.ProtoReflect.Descriptor instead. +func (*SessionState) Descriptor() ([]byte, []int) { + return file_controller_api_resources_sessions_v1_session_proto_rawDescGZIP(), []int{1} +} + +func (x *SessionState) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *SessionState) GetStartTime() *timestamp.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *SessionState) GetEndTime() *timestamp.Timestamp { + if x != nil { + return x.EndTime + } + return nil +} + // Session contains all fields related to a Session resource type Session struct { state protoimpl.MessageState @@ -40,8 +157,8 @@ type Session struct { // The ID of the resource // Output only. Id string `protobuf:"bytes,10,opt,name=id,proto3" json:"id,omitempty"` - // The id of the parent of this resource. This must be defined for creation of this resource, but is otherwise - // read only. + // The id of the parent of this resource. This must be defined for creation + // of this resource, but is otherwise read only. TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty"` // Scope information for this resource // Output only. @@ -59,25 +176,34 @@ type Session struct { Version uint32 `protobuf:"varint,70,opt,name=version,proto3" json:"version,omitempty"` // Type of the session (e.g. tcp, ssh, etc.) Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty"` + // The id of the token used to authenticate. + AuthTokenId string `protobuf:"bytes,90,opt,name=auth_token_id,proto3" json:"auth_token_id,omitempty"` // The ID of the user that requested the session - UserId string `protobuf:"bytes,90,opt,name=user_id,proto3" json:"user_id,omitempty"` - HostId string `protobuf:"bytes,100,opt,name=host_id,proto3" json:"host_id,omitempty"` - ScopeId string `protobuf:"bytes,110,opt,name=scope_id,proto3" json:"scope_id,omitempty"` + UserId string `protobuf:"bytes,100,opt,name=user_id,proto3" json:"user_id,omitempty"` + HostSetId string `protobuf:"bytes,110,opt,name=host_set_id,proto3" json:"host_set_id,omitempty"` + HostId string `protobuf:"bytes,120,opt,name=host_id,proto3" json:"host_id,omitempty"` + ScopeId string `protobuf:"bytes,130,opt,name=scope_id,proto3" json:"scope_id,omitempty"` + Endpoint string `protobuf:"bytes,140,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + // The states of this session in descending from the current state to the + // first. + States []*SessionState `protobuf:"bytes,150,rep,name=states,proto3" json:"states,omitempty"` + // The name of the current status of this session. + Status string `protobuf:"bytes,160,opt,name=status,proto3" json:"status,omitempty"` + // Worker information. The first worker in the slice should be prioritized. + WorkerInfo []*WorkerInfo `protobuf:"bytes,170,rep,name=worker_info,proto3" json:"worker_info,omitempty"` + // Deprecated, to be moved to another proto by another PR: // The certificate to use when connecting (or if using custom certs, to // serve as the "login"). Raw DER bytes. - Certificate []byte `protobuf:"bytes,120,opt,name=certificate,proto3" json:"certificate,omitempty"` + Certificate []byte `protobuf:"bytes,220,opt,name=certificate,proto3" json:"certificate,omitempty"` // The private key to use when connecting (or if using custom certs, to pass // as the "password"). - PrivateKey []byte `protobuf:"bytes,130,opt,name=private_key,proto3" json:"private_key,omitempty"` - Endpoint string `protobuf:"bytes,140,opt,name=endpoint,proto3" json:"endpoint,omitempty"` - // Worker information. The first worker in the slice should be prioritized. - WorkerInfo []*targets.WorkerInfo `protobuf:"bytes,150,rep,name=worker_info,proto3" json:"worker_info,omitempty"` + PrivateKey []byte `protobuf:"bytes,230,opt,name=private_key,proto3" json:"private_key,omitempty"` } func (x *Session) Reset() { *x = Session{} if protoimpl.UnsafeEnabled { - mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[0] + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -90,7 +216,7 @@ func (x *Session) String() string { func (*Session) ProtoMessage() {} func (x *Session) ProtoReflect() protoreflect.Message { - mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[0] + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -103,7 +229,7 @@ func (x *Session) ProtoReflect() protoreflect.Message { // Deprecated: Use Session.ProtoReflect.Descriptor instead. func (*Session) Descriptor() ([]byte, []int) { - return file_controller_api_resources_sessions_v1_session_proto_rawDescGZIP(), []int{0} + return file_controller_api_resources_sessions_v1_session_proto_rawDescGZIP(), []int{2} } func (x *Session) GetId() string { @@ -162,6 +288,13 @@ func (x *Session) GetType() string { return "" } +func (x *Session) GetAuthTokenId() string { + if x != nil { + return x.AuthTokenId + } + return "" +} + func (x *Session) GetUserId() string { if x != nil { return x.UserId @@ -169,6 +302,13 @@ func (x *Session) GetUserId() string { return "" } +func (x *Session) GetHostSetId() string { + if x != nil { + return x.HostSetId + } + return "" +} + func (x *Session) GetHostId() string { if x != nil { return x.HostId @@ -183,6 +323,34 @@ func (x *Session) GetScopeId() string { return "" } +func (x *Session) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +func (x *Session) GetStates() []*SessionState { + if x != nil { + return x.States + } + return nil +} + +func (x *Session) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *Session) GetWorkerInfo() []*WorkerInfo { + if x != nil { + return x.WorkerInfo + } + return nil +} + func (x *Session) GetCertificate() []byte { if x != nil { return x.Certificate @@ -197,20 +365,6 @@ func (x *Session) GetPrivateKey() []byte { return nil } -func (x *Session) GetEndpoint() string { - if x != nil { - return x.Endpoint - } - return "" -} - -func (x *Session) GetWorkerInfo() []*targets.WorkerInfo { - if x != nil { - return x.WorkerInfo - } - return nil -} - var File_controller_api_resources_sessions_v1_session_proto protoreflect.FileDescriptor var file_controller_api_resources_sessions_v1_session_proto_rawDesc = []byte{ @@ -234,53 +388,76 @@ var file_controller_api_resources_sessions_v1_session_proto_rawDesc = []byte{ 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x69, - 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, - 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x26, 0x0a, 0x0a, 0x57, 0x6f, 0x72, 0x6b, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, + 0x9a, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3a, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0f, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x50, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x1a, - 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x78, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0b, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x82, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x12, - 0x1b, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x8c, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x52, 0x0a, 0x0b, - 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x96, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0xa7, 0x06, 0x0a, + 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, + 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x32, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x0f, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x46, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x24, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x12, + 0x20, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x6e, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x69, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x78, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x08, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x82, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x8c, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, + 0x96, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x73, 0x12, 0x17, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0xa0, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x53, 0x0a, 0x0b, 0x77, + 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xaa, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, - 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x3b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x12, 0x21, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, + 0xdc, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x18, 0xe6, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -295,24 +472,28 @@ func file_controller_api_resources_sessions_v1_session_proto_rawDescGZIP() []byt return file_controller_api_resources_sessions_v1_session_proto_rawDescData } -var file_controller_api_resources_sessions_v1_session_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_controller_api_resources_sessions_v1_session_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_controller_api_resources_sessions_v1_session_proto_goTypes = []interface{}{ - (*Session)(nil), // 0: controller.api.resources.sessions.v1.Session - (*scopes.ScopeInfo)(nil), // 1: controller.api.resources.scopes.v1.ScopeInfo - (*timestamp.Timestamp)(nil), // 2: google.protobuf.Timestamp - (*targets.WorkerInfo)(nil), // 3: controller.api.resources.targets.v1.WorkerInfo + (*WorkerInfo)(nil), // 0: controller.api.resources.sessions.v1.WorkerInfo + (*SessionState)(nil), // 1: controller.api.resources.sessions.v1.SessionState + (*Session)(nil), // 2: controller.api.resources.sessions.v1.Session + (*timestamp.Timestamp)(nil), // 3: google.protobuf.Timestamp + (*scopes.ScopeInfo)(nil), // 4: controller.api.resources.scopes.v1.ScopeInfo } var file_controller_api_resources_sessions_v1_session_proto_depIdxs = []int32{ - 1, // 0: controller.api.resources.sessions.v1.Session.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo - 2, // 1: controller.api.resources.sessions.v1.Session.created_time:type_name -> google.protobuf.Timestamp - 2, // 2: controller.api.resources.sessions.v1.Session.updated_time:type_name -> google.protobuf.Timestamp - 2, // 3: controller.api.resources.sessions.v1.Session.expiration_time:type_name -> google.protobuf.Timestamp - 3, // 4: controller.api.resources.sessions.v1.Session.worker_info:type_name -> controller.api.resources.targets.v1.WorkerInfo - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 3, // 0: controller.api.resources.sessions.v1.SessionState.start_time:type_name -> google.protobuf.Timestamp + 3, // 1: controller.api.resources.sessions.v1.SessionState.end_time:type_name -> google.protobuf.Timestamp + 4, // 2: controller.api.resources.sessions.v1.Session.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo + 3, // 3: controller.api.resources.sessions.v1.Session.created_time:type_name -> google.protobuf.Timestamp + 3, // 4: controller.api.resources.sessions.v1.Session.updated_time:type_name -> google.protobuf.Timestamp + 3, // 5: controller.api.resources.sessions.v1.Session.expiration_time:type_name -> google.protobuf.Timestamp + 1, // 6: controller.api.resources.sessions.v1.Session.states:type_name -> controller.api.resources.sessions.v1.SessionState + 0, // 7: controller.api.resources.sessions.v1.Session.worker_info:type_name -> controller.api.resources.sessions.v1.WorkerInfo + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_controller_api_resources_sessions_v1_session_proto_init() } @@ -322,6 +503,30 @@ func file_controller_api_resources_sessions_v1_session_proto_init() { } if !protoimpl.UnsafeEnabled { file_controller_api_resources_sessions_v1_session_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkerInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_resources_sessions_v1_session_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_resources_sessions_v1_session_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Session); i { case 0: return &v.state @@ -340,7 +545,7 @@ func file_controller_api_resources_sessions_v1_session_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_api_resources_sessions_v1_session_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/gen/controller/api/services/session_service.pb.go b/internal/gen/controller/api/services/session_service.pb.go new file mode 100644 index 000000000..95f06f2b4 --- /dev/null +++ b/internal/gen/controller/api/services/session_service.pb.go @@ -0,0 +1,740 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.12.4 +// source: controller/api/services/v1/session_service.proto + +package services + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + sessions "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + _ "google.golang.org/genproto/googleapis/api/annotations" + _ "google.golang.org/genproto/protobuf/field_mask" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type GetSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + View string `protobuf:"bytes,2,opt,name=view,proto3" json:"view,omitempty"` +} + +func (x *GetSessionRequest) Reset() { + *x = GetSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSessionRequest) ProtoMessage() {} + +func (x *GetSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSessionRequest.ProtoReflect.Descriptor instead. +func (*GetSessionRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_session_service_proto_rawDescGZIP(), []int{0} +} + +func (x *GetSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetSessionRequest) GetView() string { + if x != nil { + return x.View + } + return "" +} + +type GetSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *sessions.Session `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetSessionResponse) Reset() { + *x = GetSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSessionResponse) ProtoMessage() {} + +func (x *GetSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSessionResponse.ProtoReflect.Descriptor instead. +func (*GetSessionResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_session_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetSessionResponse) GetItem() *sessions.Session { + if x != nil { + return x.Item + } + return nil +} + +type ListSessionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ScopeId string `protobuf:"bytes,1,opt,name=scope_id,json=scopeId,proto3" json:"scope_id,omitempty"` + View string `protobuf:"bytes,2,opt,name=view,proto3" json:"view,omitempty"` +} + +func (x *ListSessionsRequest) Reset() { + *x = ListSessionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSessionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSessionsRequest) ProtoMessage() {} + +func (x *ListSessionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListSessionsRequest.ProtoReflect.Descriptor instead. +func (*ListSessionsRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_session_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ListSessionsRequest) GetScopeId() string { + if x != nil { + return x.ScopeId + } + return "" +} + +func (x *ListSessionsRequest) GetView() string { + if x != nil { + return x.View + } + return "" +} + +type ListSessionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items []*sessions.Session `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *ListSessionsResponse) Reset() { + *x = ListSessionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSessionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSessionsResponse) ProtoMessage() {} + +func (x *ListSessionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListSessionsResponse.ProtoReflect.Descriptor instead. +func (*ListSessionsResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_session_service_proto_rawDescGZIP(), []int{3} +} + +func (x *ListSessionsResponse) GetItems() []*sessions.Session { + if x != nil { + return x.Items + } + return nil +} + +type CancelSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *CancelSessionRequest) Reset() { + *x = CancelSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CancelSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CancelSessionRequest) ProtoMessage() {} + +func (x *CancelSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CancelSessionRequest.ProtoReflect.Descriptor instead. +func (*CancelSessionRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_session_service_proto_rawDescGZIP(), []int{4} +} + +func (x *CancelSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *CancelSessionRequest) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +type CancelSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *sessions.Session `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *CancelSessionResponse) Reset() { + *x = CancelSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CancelSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CancelSessionResponse) ProtoMessage() {} + +func (x *CancelSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_session_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CancelSessionResponse.ProtoReflect.Descriptor instead. +func (*CancelSessionResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_session_service_proto_rawDescGZIP(), []int{5} +} + +func (x *CancelSessionResponse) GetItem() *sessions.Session { + if x != nil { + return x.Item + } + return nil +} + +var File_controller_api_services_v1_session_service_proto protoreflect.FileDescriptor + +var file_controller_api_services_v1_session_service_proto_rawDesc = []byte{ + 0x0a, 0x30, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, + 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x37, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x57, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x41, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, + 0x69, 0x74, 0x65, 0x6d, 0x22, 0x44, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x5b, 0x0a, 0x14, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x40, 0x0a, 0x14, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5a, 0x0a, 0x15, 0x43, 0x61, 0x6e, + 0x63, 0x65, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x41, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0x8f, 0x04, 0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa6, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x11, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x17, 0x12, 0x15, 0x47, 0x65, 0x74, 0x73, + 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x9e, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, + 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x92, 0x41, 0x14, 0x12, 0x12, + 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x20, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x62, 0x04, 0x69, 0x74, 0x65, + 0x6d, 0x92, 0x41, 0x13, 0x12, 0x11, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x73, 0x20, 0x61, 0x20, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_controller_api_services_v1_session_service_proto_rawDescOnce sync.Once + file_controller_api_services_v1_session_service_proto_rawDescData = file_controller_api_services_v1_session_service_proto_rawDesc +) + +func file_controller_api_services_v1_session_service_proto_rawDescGZIP() []byte { + file_controller_api_services_v1_session_service_proto_rawDescOnce.Do(func() { + file_controller_api_services_v1_session_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_api_services_v1_session_service_proto_rawDescData) + }) + return file_controller_api_services_v1_session_service_proto_rawDescData +} + +var file_controller_api_services_v1_session_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_controller_api_services_v1_session_service_proto_goTypes = []interface{}{ + (*GetSessionRequest)(nil), // 0: controller.api.services.v1.GetSessionRequest + (*GetSessionResponse)(nil), // 1: controller.api.services.v1.GetSessionResponse + (*ListSessionsRequest)(nil), // 2: controller.api.services.v1.ListSessionsRequest + (*ListSessionsResponse)(nil), // 3: controller.api.services.v1.ListSessionsResponse + (*CancelSessionRequest)(nil), // 4: controller.api.services.v1.CancelSessionRequest + (*CancelSessionResponse)(nil), // 5: controller.api.services.v1.CancelSessionResponse + (*sessions.Session)(nil), // 6: controller.api.resources.sessions.v1.Session +} +var file_controller_api_services_v1_session_service_proto_depIdxs = []int32{ + 6, // 0: controller.api.services.v1.GetSessionResponse.item:type_name -> controller.api.resources.sessions.v1.Session + 6, // 1: controller.api.services.v1.ListSessionsResponse.items:type_name -> controller.api.resources.sessions.v1.Session + 6, // 2: controller.api.services.v1.CancelSessionResponse.item:type_name -> controller.api.resources.sessions.v1.Session + 0, // 3: controller.api.services.v1.SessionService.GetSession:input_type -> controller.api.services.v1.GetSessionRequest + 2, // 4: controller.api.services.v1.SessionService.ListSessions:input_type -> controller.api.services.v1.ListSessionsRequest + 4, // 5: controller.api.services.v1.SessionService.CancelSession:input_type -> controller.api.services.v1.CancelSessionRequest + 1, // 6: controller.api.services.v1.SessionService.GetSession:output_type -> controller.api.services.v1.GetSessionResponse + 3, // 7: controller.api.services.v1.SessionService.ListSessions:output_type -> controller.api.services.v1.ListSessionsResponse + 5, // 8: controller.api.services.v1.SessionService.CancelSession:output_type -> controller.api.services.v1.CancelSessionResponse + 6, // [6:9] is the sub-list for method output_type + 3, // [3:6] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_controller_api_services_v1_session_service_proto_init() } +func file_controller_api_services_v1_session_service_proto_init() { + if File_controller_api_services_v1_session_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_controller_api_services_v1_session_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_session_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSessionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_session_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSessionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_session_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSessionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_session_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CancelSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_session_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CancelSessionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_controller_api_services_v1_session_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_controller_api_services_v1_session_service_proto_goTypes, + DependencyIndexes: file_controller_api_services_v1_session_service_proto_depIdxs, + MessageInfos: file_controller_api_services_v1_session_service_proto_msgTypes, + }.Build() + File_controller_api_services_v1_session_service_proto = out.File + file_controller_api_services_v1_session_service_proto_rawDesc = nil + file_controller_api_services_v1_session_service_proto_goTypes = nil + file_controller_api_services_v1_session_service_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// SessionServiceClient is the client API for SessionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SessionServiceClient interface { + // GetSession returns a stored Session if present. The provided request + // must include the scope and session ID for the session being retrieved. If + // any of those IDs are missing, malformed or reference a non existing + // resource an error is returned. + GetSession(ctx context.Context, in *GetSessionRequest, opts ...grpc.CallOption) (*GetSessionResponse, error) + // ListSessions returns a list of stored sessions which exist inside the project + // referenced inside the request. The request must include the scope ID for + // the sessions being retrieved. If the scope ID is missing, malformed, or + // reference a non existing scope, an error is returned. + ListSessions(ctx context.Context, in *ListSessionsRequest, opts ...grpc.CallOption) (*ListSessionsResponse, error) + // CancelSession cancels an existing session in boundary. An error + // is returned if the request attempts to cancel a session that does + // not exist. + CancelSession(ctx context.Context, in *CancelSessionRequest, opts ...grpc.CallOption) (*CancelSessionResponse, error) +} + +type sessionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSessionServiceClient(cc grpc.ClientConnInterface) SessionServiceClient { + return &sessionServiceClient{cc} +} + +func (c *sessionServiceClient) GetSession(ctx context.Context, in *GetSessionRequest, opts ...grpc.CallOption) (*GetSessionResponse, error) { + out := new(GetSessionResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.SessionService/GetSession", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionServiceClient) ListSessions(ctx context.Context, in *ListSessionsRequest, opts ...grpc.CallOption) (*ListSessionsResponse, error) { + out := new(ListSessionsResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.SessionService/ListSessions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionServiceClient) CancelSession(ctx context.Context, in *CancelSessionRequest, opts ...grpc.CallOption) (*CancelSessionResponse, error) { + out := new(CancelSessionResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.SessionService/CancelSession", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SessionServiceServer is the server API for SessionService service. +type SessionServiceServer interface { + // GetSession returns a stored Session if present. The provided request + // must include the scope and session ID for the session being retrieved. If + // any of those IDs are missing, malformed or reference a non existing + // resource an error is returned. + GetSession(context.Context, *GetSessionRequest) (*GetSessionResponse, error) + // ListSessions returns a list of stored sessions which exist inside the project + // referenced inside the request. The request must include the scope ID for + // the sessions being retrieved. If the scope ID is missing, malformed, or + // reference a non existing scope, an error is returned. + ListSessions(context.Context, *ListSessionsRequest) (*ListSessionsResponse, error) + // CancelSession cancels an existing session in boundary. An error + // is returned if the request attempts to cancel a session that does + // not exist. + CancelSession(context.Context, *CancelSessionRequest) (*CancelSessionResponse, error) +} + +// UnimplementedSessionServiceServer can be embedded to have forward compatible implementations. +type UnimplementedSessionServiceServer struct { +} + +func (*UnimplementedSessionServiceServer) GetSession(context.Context, *GetSessionRequest) (*GetSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSession not implemented") +} +func (*UnimplementedSessionServiceServer) ListSessions(context.Context, *ListSessionsRequest) (*ListSessionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListSessions not implemented") +} +func (*UnimplementedSessionServiceServer) CancelSession(context.Context, *CancelSessionRequest) (*CancelSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CancelSession not implemented") +} + +func RegisterSessionServiceServer(s *grpc.Server, srv SessionServiceServer) { + s.RegisterService(&_SessionService_serviceDesc, srv) +} + +func _SessionService_GetSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).GetSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.SessionService/GetSession", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).GetSession(ctx, req.(*GetSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionService_ListSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListSessionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).ListSessions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.SessionService/ListSessions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).ListSessions(ctx, req.(*ListSessionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionService_CancelSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CancelSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).CancelSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.SessionService/CancelSession", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).CancelSession(ctx, req.(*CancelSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _SessionService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "controller.api.services.v1.SessionService", + HandlerType: (*SessionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetSession", + Handler: _SessionService_GetSession_Handler, + }, + { + MethodName: "ListSessions", + Handler: _SessionService_ListSessions_Handler, + }, + { + MethodName: "CancelSession", + Handler: _SessionService_CancelSession_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "controller/api/services/v1/session_service.proto", +} diff --git a/internal/gen/controller/api/services/session_service.pb.gw.go b/internal/gen/controller/api/services/session_service.pb.gw.go new file mode 100644 index 000000000..949e9def9 --- /dev/null +++ b/internal/gen/controller/api/services/session_service.pb.gw.go @@ -0,0 +1,410 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: controller/api/services/v1/session_service.proto + +/* +Package services is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package services + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray + +var ( + filter_SessionService_GetSession_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_SessionService_GetSession_0(ctx context.Context, marshaler runtime.Marshaler, client SessionServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetSessionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SessionService_GetSession_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetSession(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_SessionService_GetSession_0(ctx context.Context, marshaler runtime.Marshaler, server SessionServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetSessionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SessionService_GetSession_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetSession(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_SessionService_ListSessions_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_SessionService_ListSessions_0(ctx context.Context, marshaler runtime.Marshaler, client SessionServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListSessionsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SessionService_ListSessions_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListSessions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_SessionService_ListSessions_0(ctx context.Context, marshaler runtime.Marshaler, server SessionServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListSessionsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SessionService_ListSessions_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListSessions(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_SessionService_CancelSession_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_SessionService_CancelSession_0(ctx context.Context, marshaler runtime.Marshaler, client SessionServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CancelSessionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SessionService_CancelSession_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CancelSession(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_SessionService_CancelSession_0(ctx context.Context, marshaler runtime.Marshaler, server SessionServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CancelSessionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SessionService_CancelSession_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CancelSession(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterSessionServiceHandlerServer registers the http handlers for service SessionService to "mux". +// UnaryRPC :call SessionServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterSessionServiceHandlerFromEndpoint instead. +func RegisterSessionServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server SessionServiceServer) error { + + mux.Handle("GET", pattern_SessionService_GetSession_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/controller.api.services.v1.SessionService/GetSession") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_SessionService_GetSession_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SessionService_GetSession_0(ctx, mux, outboundMarshaler, w, req, response_SessionService_GetSession_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_SessionService_ListSessions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/controller.api.services.v1.SessionService/ListSessions") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_SessionService_ListSessions_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SessionService_ListSessions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_SessionService_CancelSession_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/controller.api.services.v1.SessionService/CancelSession") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_SessionService_CancelSession_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SessionService_CancelSession_0(ctx, mux, outboundMarshaler, w, req, response_SessionService_CancelSession_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterSessionServiceHandlerFromEndpoint is same as RegisterSessionServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterSessionServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterSessionServiceHandler(ctx, mux, conn) +} + +// RegisterSessionServiceHandler registers the http handlers for service SessionService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterSessionServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterSessionServiceHandlerClient(ctx, mux, NewSessionServiceClient(conn)) +} + +// RegisterSessionServiceHandlerClient registers the http handlers for service SessionService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "SessionServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SessionServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "SessionServiceClient" to call the correct interceptors. +func RegisterSessionServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SessionServiceClient) error { + + mux.Handle("GET", pattern_SessionService_GetSession_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/controller.api.services.v1.SessionService/GetSession") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_SessionService_GetSession_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SessionService_GetSession_0(ctx, mux, outboundMarshaler, w, req, response_SessionService_GetSession_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_SessionService_ListSessions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/controller.api.services.v1.SessionService/ListSessions") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_SessionService_ListSessions_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SessionService_ListSessions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_SessionService_CancelSession_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/controller.api.services.v1.SessionService/CancelSession") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_SessionService_CancelSession_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SessionService_CancelSession_0(ctx, mux, outboundMarshaler, w, req, response_SessionService_CancelSession_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +type response_SessionService_GetSession_0 struct { + proto.Message +} + +func (m response_SessionService_GetSession_0) XXX_ResponseBody() interface{} { + response := m.Message.(*GetSessionResponse) + return response.Item +} + +type response_SessionService_CancelSession_0 struct { + proto.Message +} + +func (m response_SessionService_CancelSession_0) XXX_ResponseBody() interface{} { + response := m.Message.(*CancelSessionResponse) + return response.Item +} + +var ( + pattern_SessionService_GetSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "sessions", "id"}, "")) + + pattern_SessionService_ListSessions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "sessions"}, "")) + + pattern_SessionService_CancelSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "sessions", "id"}, "cancel")) +) + +var ( + forward_SessionService_GetSession_0 = runtime.ForwardResponseMessage + + forward_SessionService_ListSessions_0 = runtime.ForwardResponseMessage + + forward_SessionService_CancelSession_0 = runtime.ForwardResponseMessage +) diff --git a/internal/proto/local/controller/api/resources/sessions/v1/session.proto b/internal/proto/local/controller/api/resources/sessions/v1/session.proto index 8ab7208d5..9f065bea9 100644 --- a/internal/proto/local/controller/api/resources/sessions/v1/session.proto +++ b/internal/proto/local/controller/api/resources/sessions/v1/session.proto @@ -11,55 +11,92 @@ import "controller/api/resources/scopes/v1/scope.proto"; import "controller/api/resources/targets/v1/target.proto"; import "controller/custom_options/v1/options.proto"; +message WorkerInfo { + // The address of the worker + string address = 10; +} + +message SessionState { + // This is the status of the session. For example "pending", "active", + // "canceling", "terminated". + string status = 10; + + // The time the session entered this state. + // Output only. + google.protobuf.Timestamp start_time = 20 [json_name = "start_time"]; + + // The time the session stopped being in this state. + // Output only. + google.protobuf.Timestamp end_time = 30 [json_name = "end_time"]; +} + // Session contains all fields related to a Session resource message Session { - // The ID of the resource - // Output only. - string id = 10; + // The ID of the resource + // Output only. + string id = 10; - // The id of the parent of this resource. This must be defined for creation of this resource, but is otherwise - // read only. - string target_id = 20 [json_name="target_id"]; + // The id of the parent of this resource. This must be defined for creation + // of this resource, but is otherwise read only. + string target_id = 20 [json_name = "target_id"]; - // Scope information for this resource - // Output only. - resources.scopes.v1.ScopeInfo scope = 30; + // Scope information for this resource + // Output only. + resources.scopes.v1.ScopeInfo scope = 30; - // The time this resource was created - // Output only. - google.protobuf.Timestamp created_time = 40 [json_name="created_time"]; + // The time this resource was created + // Output only. + google.protobuf.Timestamp created_time = 40 [json_name = "created_time"]; - // The time this resource was last updated. - // Output only. - google.protobuf.Timestamp updated_time = 50 [json_name="updated_time"]; + // The time this resource was last updated. + // Output only. + google.protobuf.Timestamp updated_time = 50 [json_name = "updated_time"]; - // After this time the connection will be expired, e.g. forcefully terminated - google.protobuf.Timestamp expiration_time = 60 [json_name="expiration_time"]; + // After this time the connection will be expired, e.g. forcefully terminated + google.protobuf.Timestamp expiration_time = 60 + [json_name = "expiration_time"]; - // The version can be used in subsequent write requests to ensure this - // resource has not changed and to fail the write if it has. - uint32 version = 70; + // The version can be used in subsequent write requests to ensure this + // resource has not changed and to fail the write if it has. + uint32 version = 70; - // Type of the session (e.g. tcp, ssh, etc.) - string type = 80; + // Type of the session (e.g. tcp, ssh, etc.) + string type = 80; - // The ID of the user that requested the session - string user_id = 90 [json_name="user_id"]; + // The id of the token used to authenticate. + string auth_token_id = 90 [json_name = "auth_token_id"]; - string host_id = 100 [json_name="host_id"]; + // The ID of the user that requested the session + string user_id = 100 [json_name = "user_id"]; - string scope_id = 110 [json_name="scope_id"]; + // The host set id used by the session's target + string host_set_id = 110 [json_name = "host_set_id"]; - // The certificate to use when connecting (or if using custom certs, to - // serve as the "login"). Raw DER bytes. - bytes certificate = 120; + // The host id used by the session + string host_id = 120 [json_name = "host_id"]; - // The private key to use when connecting (or if using custom certs, to pass - // as the "password"). - bytes private_key = 130 [json_name="private_key"]; + // The scope of the session + string scope_id = 130 [json_name = "scope_id"]; - string endpoint = 140; + // The endpoint of the session + string endpoint = 140; - // Worker information. The first worker in the slice should be prioritized. - repeated resources.targets.v1.WorkerInfo worker_info = 150 [json_name="worker_info"]; + // The states of this session in descending from the current state to the + // first. + repeated SessionState states = 150; + + // The name of the current status of this session. + string status = 160; + + // Worker information. The first worker in the slice should be prioritized. + repeated WorkerInfo worker_info = 170 [json_name = "worker_info"]; + + // Deprecated, to be moved to another proto by another PR: + // The certificate to use when connecting (or if using custom certs, to + // serve as the "login"). Raw DER bytes. + bytes certificate = 220; + + // The private key to use when connecting (or if using custom certs, to pass + // as the "password"). + bytes private_key = 230 [json_name = "private_key"]; } diff --git a/internal/proto/local/controller/api/services/v1/session_service.proto b/internal/proto/local/controller/api/services/v1/session_service.proto new file mode 100644 index 000000000..f6eb2a407 --- /dev/null +++ b/internal/proto/local/controller/api/services/v1/session_service.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; + +package controller.api.services.v1; + +option go_package = "github.com/hashicorp/boundary/internal/gen/controller/api/services;services"; + +import "protoc-gen-openapiv2/options/annotations.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/field_mask.proto"; +import "controller/api/resources/sessions/v1/session.proto"; + +service SessionService { + // GetSession returns a stored Session if present. The provided request + // must include the scope and session ID for the session being retrieved. If + // any of those IDs are missing, malformed or reference a non existing + // resource an error is returned. + rpc GetSession(GetSessionRequest) returns (GetSessionResponse) { + option (google.api.http) = { + get: "/v1/sessions/{id}" + response_body: "item" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Gets a single Session" + }; + } + + // ListSessions returns a list of stored sessions which exist inside the project + // referenced inside the request. The request must include the scope ID for + // the sessions being retrieved. If the scope ID is missing, malformed, or + // reference a non existing scope, an error is returned. + rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse) { + option (google.api.http) = { + get: "/v1/sessions" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Lists all Sessions" + }; + } + + // CancelSession cancels an existing session in boundary. An error + // is returned if the request attempts to cancel a session that does + // not exist. + rpc CancelSession(CancelSessionRequest) returns (CancelSessionResponse) { + option (google.api.http) = { + post: "/v1/sessions/{id}:cancel" + response_body: "item" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Cancels a Session" + }; + } +} + +message GetSessionRequest { + string id = 1; + string view = 2; +} + +message GetSessionResponse { + resources.sessions.v1.Session item = 1; +} + +message ListSessionsRequest { + string scope_id = 1; + string view = 2; +} + +message ListSessionsResponse { + repeated resources.sessions.v1.Session items = 1; +} + +message CancelSessionRequest { + string id = 1; + uint32 version = 2; +} + +message CancelSessionResponse { + resources.sessions.v1.Session item = 1; +} diff --git a/internal/servers/controller/common/common.go b/internal/servers/controller/common/common.go index 8f3e1c03f..1823289bc 100644 --- a/internal/servers/controller/common/common.go +++ b/internal/servers/controller/common/common.go @@ -16,6 +16,6 @@ type ( PasswordAuthRepoFactory func() (*password.Repository, error) ServersRepoFactory func() (*servers.Repository, error) StaticRepoFactory func() (*static.Repository, error) - TargetRepoFactory func() (*target.Repository, error) SessionRepoFactory func() (*session.Repository, error) + TargetRepoFactory func() (*target.Repository, error) ) diff --git a/internal/servers/controller/controller.go b/internal/servers/controller/controller.go index 10fa7eb92..ce8c03b07 100644 --- a/internal/servers/controller/controller.go +++ b/internal/servers/controller/controller.go @@ -42,9 +42,9 @@ type Controller struct { IamRepoFn common.IamRepoFactory PasswordAuthRepoFn common.PasswordAuthRepoFactory ServersRepoFn common.ServersRepoFactory + SessionRepoFn common.SessionRepoFactory StaticHostRepoFn common.StaticRepoFactory TargetRepoFn common.TargetRepoFactory - SessionRepoFn common.SessionRepoFactory kms *kms.Kms diff --git a/internal/servers/controller/handler.go b/internal/servers/controller/handler.go index 331f1bf2a..70b4e2a1d 100644 --- a/internal/servers/controller/handler.go +++ b/internal/servers/controller/handler.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/boundary/internal/servers/controller/handlers/accounts" "github.com/hashicorp/boundary/internal/servers/controller/handlers/authmethods" "github.com/hashicorp/boundary/internal/servers/controller/handlers/host_sets" + "github.com/hashicorp/boundary/internal/servers/controller/handlers/sessions" "github.com/hashicorp/boundary/internal/servers/controller/handlers/targets" "github.com/hashicorp/boundary/sdk/strutil" "github.com/hashicorp/shared-secure-libs/configutil" @@ -169,6 +170,13 @@ func handleGrpcGateway(c *Controller, props HandlerProperties) (http.Handler, er if err := services.RegisterRoleServiceHandlerServer(ctx, mux, rs); err != nil { return nil, fmt.Errorf("failed to register role service handler: %w", err) } + ss, err := sessions.NewService(c.SessionRepoFn, c.IamRepoFn) + if err != nil { + return nil, fmt.Errorf("failed to create session handler service: %w", err) + } + if err := services.RegisterSessionServiceHandlerServer(ctx, mux, ss); err != nil { + return nil, fmt.Errorf("failed to register session service handler: %w", err) + } return mux, nil } diff --git a/internal/servers/controller/handler_test.go b/internal/servers/controller/handler_test.go index ddd2b0b53..be73b9430 100644 --- a/internal/servers/controller/handler_test.go +++ b/internal/servers/controller/handler_test.go @@ -93,7 +93,8 @@ func TestHandleImplementedPaths(t *testing.T) { for verb, paths := range map[string][]string{ "GET": { - // new paths + "v1/sessions/", + "v1/sessions/someid", "v1/scopes", "v1/scopes/someid", "v1/auth-tokens", @@ -119,7 +120,6 @@ func TestHandleImplementedPaths(t *testing.T) { }, "POST": { // Creation end points - // new paths "v1/scopes", "v1/groups", "v1/roles", @@ -132,6 +132,7 @@ func TestHandleImplementedPaths(t *testing.T) { "v1/targets", // custom methods + "v1/sessions/someid:cancel", "v1/auth-methods/someid:authenticate", "v1/accounts/someid:set-password", "v1/accounts/someid:change-password", @@ -146,7 +147,6 @@ func TestHandleImplementedPaths(t *testing.T) { "v1/groups/someid:remove-members", }, "DELETE": { - // new paths "v1/scopes/someid", "v1/users/someid", "v1/roles/someid", @@ -160,7 +160,6 @@ func TestHandleImplementedPaths(t *testing.T) { "v1/targets/someid", }, "PATCH": { - // new paths "v1/scopes/someid", "v1/users/someid", "v1/roles/someid", diff --git a/internal/servers/controller/handlers/sessions/session_service.go b/internal/servers/controller/handlers/sessions/session_service.go new file mode 100644 index 000000000..2e2cf51a7 --- /dev/null +++ b/internal/servers/controller/handlers/sessions/session_service.go @@ -0,0 +1,253 @@ +package sessions + +import ( + "context" + "errors" + "fmt" + + "github.com/hashicorp/boundary/internal/auth" + "github.com/hashicorp/boundary/internal/db" + pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" + "github.com/hashicorp/boundary/internal/servers/controller/common" + "github.com/hashicorp/boundary/internal/servers/controller/handlers" + "github.com/hashicorp/boundary/internal/session" + "github.com/hashicorp/boundary/internal/types/action" + "github.com/hashicorp/boundary/internal/types/resource" + "github.com/hashicorp/boundary/internal/types/scope" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// Service handles request as described by the pbs.SessionServiceServer interface. +type Service struct { + repoFn common.SessionRepoFactory + iamRepoFn common.IamRepoFactory +} + +// NewService returns a session service which handles session related requests to boundary. +func NewService(repoFn common.SessionRepoFactory, iamRepoFn common.IamRepoFactory) (Service, error) { + if repoFn == nil { + return Service{}, fmt.Errorf("nil session repository provided") + } + if iamRepoFn == nil { + return Service{}, fmt.Errorf("nil iam repository provided") + } + return Service{repoFn: repoFn, iamRepoFn: iamRepoFn}, nil +} + +var _ pbs.SessionServiceServer = Service{} + +// GetSessions implements the interface pbs.SessionServiceServer. +func (s Service) GetSession(ctx context.Context, req *pbs.GetSessionRequest) (*pbs.GetSessionResponse, error) { + if err := validateGetRequest(req); err != nil { + return nil, err + } + authResults := s.authResult(ctx, req.GetId(), action.Read) + if authResults.Error != nil { + return nil, authResults.Error + } + ses, err := s.getFromRepo(ctx, req.GetId()) + if err != nil { + return nil, err + } + ses.Scope = authResults.Scope + return &pbs.GetSessionResponse{Item: ses}, nil +} + +// ListSessions implements the interface pbs.SessionServiceServer. +func (s Service) ListSessions(ctx context.Context, req *pbs.ListSessionsRequest) (*pbs.ListSessionsResponse, error) { + if err := validateListRequest(req); err != nil { + return nil, err + } + authResults := s.authResult(ctx, req.GetScopeId(), action.List) + if authResults.Error != nil { + return nil, authResults.Error + } + seslist, err := s.listFromRepo(ctx, authResults.Scope.GetId()) + if err != nil { + return nil, err + } + for _, item := range seslist { + item.Scope = authResults.Scope + } + return &pbs.ListSessionsResponse{Items: seslist}, nil +} + +// CancelSession implements the interface pbs.SessionServiceServer. +func (s Service) CancelSession(ctx context.Context, req *pbs.CancelSessionRequest) (*pbs.CancelSessionResponse, error) { + if err := validateCancelRequest(req); err != nil { + return nil, err + } + authResults := s.authResult(ctx, req.GetId(), action.Cancel) + if authResults.Error != nil { + return nil, authResults.Error + } + ses, err := s.cancelInRepo(ctx, req.GetId(), req.GetVersion()) + if err != nil { + return nil, err + } + ses.Scope = authResults.Scope + return &pbs.CancelSessionResponse{Item: ses}, nil +} + +func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Session, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + sess, err := repo.LookupSession(ctx, id) + if err != nil { + if errors.Is(err, db.ErrRecordNotFound) { + return nil, handlers.NotFoundErrorf("Session %q doesn't exist.", id) + } + return nil, err + } + if sess == nil { + return nil, handlers.NotFoundErrorf("Session %q doesn't exist.", id) + } + return toProto(sess), nil +} + +func (s Service) listFromRepo(ctx context.Context, scopeId string) ([]*pb.Session, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + seslist, err := repo.ListSessions(ctx, session.WithScopeId(scopeId)) + if err != nil { + return nil, err + } + var outSl []*pb.Session + for _, ses := range seslist { + outSl = append(outSl, toProto(ses)) + } + return outSl, nil +} + +func (s Service) cancelInRepo(ctx context.Context, id string, version uint32) (*pb.Session, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + out, err := repo.CancelSession(ctx, id, version) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to update session: %v.", err) + } + return toProto(out), nil +} + +func (s Service) authResult(ctx context.Context, id string, a action.Type) auth.VerifyResults { + res := auth.VerifyResults{} + + var parentId string + opts := []auth.Option{auth.WithType(resource.Session), auth.WithAction(a)} + switch a { + case action.List: + parentId = id + iamRepo, err := s.iamRepoFn() + if err != nil { + res.Error = err + return res + } + scp, err := iamRepo.LookupScope(ctx, parentId) + if err != nil { + res.Error = err + return res + } + if scp == nil { + res.Error = handlers.NotFoundError() + return res + } + case action.Read, action.Cancel: + repo, err := s.repoFn() + if err != nil { + res.Error = err + return res + } + t, err := repo.LookupSession(ctx, id) + if err != nil { + res.Error = err + return res + } + if t == nil { + res.Error = handlers.NotFoundError() + return res + } + parentId = t.ScopeId + opts = append(opts, auth.WithId(id)) + default: + res.Error = errors.New("unsupported action") + return res + } + opts = append(opts, auth.WithScopeId(parentId)) + return auth.Verify(ctx, opts...) +} + +func toProto(in *session.Session) *pb.Session { + out := pb.Session{ + Id: in.GetPublicId(), + ScopeId: in.ScopeId, + TargetId: in.TargetId, + Version: in.Version, + UserId: in.UserId, + HostId: in.HostId, + HostSetId: in.HostSetId, + AuthTokenId: in.AuthTokenId, + // TODO: Provide the ServerType and the ServerId when that information becomes relevant in the API. + + CreatedTime: in.CreateTime.GetTimestamp(), + UpdatedTime: in.UpdateTime.GetTimestamp(), + ExpirationTime: in.ExpirationTime.GetTimestamp(), + } + if len(in.States) > 0 { + out.Status = in.States[0].Status.String() + } + for _, s := range in.States { + sessState := &pb.SessionState{ + Status: s.Status.String(), + } + if s.StartTime != nil { + sessState.StartTime = s.StartTime.GetTimestamp() + } + if s.EndTime != nil { + sessState.EndTime = s.EndTime.GetTimestamp() + } + out.States = append(out.States, sessState) + } + return &out +} + +// A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce +// requirements on the structure of the request. They verify that: +// * The path passed in is correctly formatted +// * All required parameters are set +// * There are no conflicting parameters provided +func validateGetRequest(req *pbs.GetSessionRequest) error { + return handlers.ValidateGetRequest(session.SessionPrefix, req, handlers.NoopValidatorFn) +} + +func validateListRequest(req *pbs.ListSessionsRequest) error { + badFields := map[string]string{} + if !handlers.ValidId(scope.Project.Prefix(), req.GetScopeId()) { + badFields["scope_id"] = "This field is required to have a properly formatted project scope id." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields) + } + return nil +} + +func validateCancelRequest(req *pbs.CancelSessionRequest) error { + badFields := map[string]string{} + if !handlers.ValidId(session.SessionPrefix, req.GetId()) { + badFields["id"] = "Impropperly formatted identifier." + } + if req.GetVersion() == 0 { + badFields["version"] = "Required field." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields) + } + return nil +} diff --git a/internal/servers/controller/handlers/sessions/session_service_test.go b/internal/servers/controller/handlers/sessions/session_service_test.go new file mode 100644 index 000000000..5c6cd92ad --- /dev/null +++ b/internal/servers/controller/handlers/sessions/session_service_test.go @@ -0,0 +1,369 @@ +package sessions_test + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/boundary/internal/auth" + "github.com/hashicorp/boundary/internal/authtoken" + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/gen/controller/api/resources/scopes" + pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" + "github.com/hashicorp/boundary/internal/host/static" + "github.com/hashicorp/boundary/internal/iam" + "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/servers/controller/handlers/sessions" + "github.com/hashicorp/boundary/internal/session" + "github.com/hashicorp/boundary/internal/target" + "github.com/hashicorp/boundary/internal/types/scope" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/testing/protocmp" +) + +func TestGetSession(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + wrap := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrap) + + iamRepo := iam.TestRepo(t, conn, wrap) + + rw := db.New(conn) + sessRepo, err := session.NewRepository(rw, rw, kms) + require.NoError(t, err) + + iamRepoFn := func() (*iam.Repository, error) { + return iamRepo, nil + } + sessRepoFn := func() (*session.Repository, error) { + return sessRepo, nil + } + + o, p := iam.TestScopes(t, iamRepo) + at := authtoken.TestAuthToken(t, conn, kms, o.GetPublicId()) + uId := at.GetIamUserId() + hc := static.TestCatalogs(t, conn, p.GetPublicId(), 1)[0] + hs := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] + h := static.TestHosts(t, conn, hc.GetPublicId(), 1)[0] + static.TestSetMembers(t, conn, hs.GetPublicId(), []*static.Host{h}) + tar := target.TestTcpTarget(t, conn, p.GetPublicId(), "test", target.WithHostSets([]string{hs.GetPublicId()})) + + sess := session.TestSession(t, conn, wrap, session.ComposedOf{ + UserId: uId, + HostId: h.GetPublicId(), + TargetId: tar.GetPublicId(), + HostSetId: hs.GetPublicId(), + AuthTokenId: at.GetPublicId(), + ScopeId: p.GetPublicId(), + Endpoint: "tcp://127.0.0.1:22", + }) + + wireSess := &pb.Session{ + Id: sess.GetPublicId(), + ScopeId: p.GetPublicId(), + AuthTokenId: at.GetPublicId(), + UserId: at.GetIamUserId(), + TargetId: sess.TargetId, + HostSetId: sess.HostSetId, + HostId: sess.HostId, + Version: sess.Version, + Status: session.StatusPending.String(), + UpdatedTime: sess.UpdateTime.GetTimestamp(), + CreatedTime: sess.CreateTime.GetTimestamp(), + ExpirationTime: sess.ExpirationTime.GetTimestamp(), + Scope: &scopes.ScopeInfo{Id: p.GetPublicId(), Type: scope.Project.String()}, + States: []*pb.SessionState{{Status: session.StatusPending.String(), StartTime: sess.CreateTime.GetTimestamp()}}, + } + + cases := []struct { + name string + scopeId string + req *pbs.GetSessionRequest + res *pbs.GetSessionResponse + errCode codes.Code + }{ + { + name: "Get a session", + scopeId: sess.ScopeId, + req: &pbs.GetSessionRequest{Id: sess.GetPublicId()}, + res: &pbs.GetSessionResponse{Item: wireSess}, + errCode: codes.OK, + }, + { + name: "Get a non existant Session", + req: &pbs.GetSessionRequest{Id: session.SessionPrefix + "_DoesntExis"}, + res: nil, + errCode: codes.NotFound, + }, + { + name: "Wrong id prefix", + req: &pbs.GetSessionRequest{Id: "j_1234567890"}, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "space in id", + req: &pbs.GetSessionRequest{Id: session.SessionPrefix + "_1 23456789"}, + res: nil, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + s, err := sessions.NewService(sessRepoFn, iamRepoFn) + require.NoError(err, "Couldn't create new session service.") + + got, gErr := s.GetSession(auth.DisabledAuthTestContext(auth.WithScopeId(tc.scopeId)), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "GetSession(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "GetSession(%q) got response\n%q, wanted\n%q", tc.req, got, tc.res) + }) + } +} + +func TestList(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + wrap := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrap) + + iamRepo := iam.TestRepo(t, conn, wrap) + + rw := db.New(conn) + sessRepo, err := session.NewRepository(rw, rw, kms) + require.NoError(t, err) + + iamRepoFn := func() (*iam.Repository, error) { + return iamRepo, nil + } + sessRepoFn := func() (*session.Repository, error) { + return sessRepo, nil + } + + _, pNoSessions := iam.TestScopes(t, iamRepo) + o, pWithSessions := iam.TestScopes(t, iamRepo) + + at := authtoken.TestAuthToken(t, conn, kms, o.GetPublicId()) + uId := at.GetIamUserId() + hc := static.TestCatalogs(t, conn, pWithSessions.GetPublicId(), 1)[0] + hs := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] + h := static.TestHosts(t, conn, hc.GetPublicId(), 1)[0] + static.TestSetMembers(t, conn, hs.GetPublicId(), []*static.Host{h}) + tar := target.TestTcpTarget(t, conn, pWithSessions.GetPublicId(), "test", target.WithHostSets([]string{hs.GetPublicId()})) + + var wantSession []*pb.Session + for i := 0; i < 10; i++ { + sess := session.TestSession(t, conn, wrap, session.ComposedOf{ + UserId: uId, + HostId: h.GetPublicId(), + TargetId: tar.GetPublicId(), + HostSetId: hs.GetPublicId(), + AuthTokenId: at.GetPublicId(), + ScopeId: pWithSessions.GetPublicId(), + Endpoint: "tcp://127.0.0.1:22", + }) + + status, states := convertStates(sess.States) + + wantSession = append(wantSession, &pb.Session{ + Id: sess.GetPublicId(), + ScopeId: pWithSessions.GetPublicId(), + AuthTokenId: at.GetPublicId(), + UserId: at.GetIamUserId(), + TargetId: sess.TargetId, + HostSetId: sess.HostSetId, + HostId: sess.HostId, + Version: sess.Version, + UpdatedTime: sess.UpdateTime.GetTimestamp(), + CreatedTime: sess.CreateTime.GetTimestamp(), + ExpirationTime: sess.ExpirationTime.GetTimestamp(), + Scope: &scopes.ScopeInfo{Id: pWithSessions.GetPublicId(), Type: scope.Project.String()}, + Status: status, + States: states, + }) + } + + cases := []struct { + name string + req *pbs.ListSessionsRequest + res *pbs.ListSessionsResponse + errCode codes.Code + }{ + { + name: "List Many Sessions", + req: &pbs.ListSessionsRequest{ScopeId: pWithSessions.GetPublicId()}, + res: &pbs.ListSessionsResponse{Items: wantSession}, + errCode: codes.OK, + }, + { + name: "List No Sessions", + req: &pbs.ListSessionsRequest{ScopeId: pNoSessions.GetPublicId()}, + res: &pbs.ListSessionsResponse{}, + errCode: codes.OK, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + s, err := sessions.NewService(sessRepoFn, iamRepoFn) + require.NoError(t, err, "Couldn't create new session service.") + + got, gErr := s.ListSessions(auth.DisabledAuthTestContext(auth.WithScopeId(tc.req.GetScopeId())), tc.req) + assert.Equal(t, tc.errCode, status.Code(gErr), "ListSessions(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + assert.Empty(t, cmp.Diff(got, tc.res, protocmp.Transform()), "ListSessions(%q) got response %q, wanted %q", tc.req, got, tc.res) + }) + } +} + +func convertStates(in []*session.State) (string, []*pb.SessionState) { + out := make([]*pb.SessionState, 0, len(in)) + for _, s := range in { + sessState := &pb.SessionState{ + Status: s.Status.String(), + } + if s.StartTime != nil { + sessState.StartTime = s.StartTime.GetTimestamp() + } + if s.EndTime != nil { + sessState.EndTime = s.EndTime.GetTimestamp() + } + out = append(out, sessState) + } + return out[0].Status, out +} + +func TestCancel(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + wrap := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrap) + + iamRepo := iam.TestRepo(t, conn, wrap) + + rw := db.New(conn) + sessRepo, err := session.NewRepository(rw, rw, kms) + require.NoError(t, err) + + iamRepoFn := func() (*iam.Repository, error) { + return iamRepo, nil + } + sessRepoFn := func() (*session.Repository, error) { + return sessRepo, nil + } + + o, p := iam.TestScopes(t, iamRepo) + at := authtoken.TestAuthToken(t, conn, kms, o.GetPublicId()) + uId := at.GetIamUserId() + hc := static.TestCatalogs(t, conn, p.GetPublicId(), 1)[0] + hs := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] + h := static.TestHosts(t, conn, hc.GetPublicId(), 1)[0] + static.TestSetMembers(t, conn, hs.GetPublicId(), []*static.Host{h}) + tar := target.TestTcpTarget(t, conn, p.GetPublicId(), "test", target.WithHostSets([]string{hs.GetPublicId()})) + + sess := session.TestSession(t, conn, wrap, session.ComposedOf{ + UserId: uId, + HostId: h.GetPublicId(), + TargetId: tar.GetPublicId(), + HostSetId: hs.GetPublicId(), + AuthTokenId: at.GetPublicId(), + ScopeId: p.GetPublicId(), + Endpoint: "tcp://127.0.0.1:22", + }) + + wireSess := &pb.Session{ + Id: sess.GetPublicId(), + ScopeId: p.GetPublicId(), + AuthTokenId: at.GetPublicId(), + UserId: at.GetIamUserId(), + TargetId: sess.TargetId, + HostSetId: sess.HostSetId, + HostId: sess.HostId, + Version: sess.Version, + CreatedTime: sess.CreateTime.GetTimestamp(), + ExpirationTime: sess.ExpirationTime.GetTimestamp(), + Scope: &scopes.ScopeInfo{Id: p.GetPublicId(), Type: scope.Project.String()}, + Status: session.StatusCancelling.String(), + } + + version := wireSess.GetVersion() + + cases := []struct { + name string + scopeId string + req *pbs.CancelSessionRequest + res *pbs.CancelSessionResponse + errCode codes.Code + }{ + { + name: "Cancel a session", + scopeId: sess.ScopeId, + req: &pbs.CancelSessionRequest{Id: sess.GetPublicId()}, + res: &pbs.CancelSessionResponse{Item: wireSess}, + errCode: codes.OK, + }, + { + name: "Cancel a non existing Session", + req: &pbs.CancelSessionRequest{Id: session.SessionPrefix + "_DoesntExis"}, + res: nil, + errCode: codes.NotFound, + }, + { + name: "Wrong id prefix", + req: &pbs.CancelSessionRequest{Id: "j_1234567890"}, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "space in id", + req: &pbs.CancelSessionRequest{Id: session.SessionPrefix + "_1 23456789"}, + res: nil, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + s, err := sessions.NewService(sessRepoFn, iamRepoFn) + require.NoError(err, "Couldn't create new session service.") + + tc.req.Version = version + + got, gErr := s.CancelSession(auth.DisabledAuthTestContext(auth.WithScopeId(tc.scopeId)), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "GetSession(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + + if tc.res == nil { + require.Nil(got) + return + } + tc.res.GetItem().Version = got.GetItem().Version + + // Compare the new cancelling state and then remove it for the rest of the proto comparison + assert.True(got.GetItem().GetUpdatedTime().AsTime().After(got.GetItem().GetCreatedTime().AsTime())) + assert.Len(got.GetItem().GetStates(), 2) + + wantState := []*pb.SessionState{ + { + Status: session.StatusCancelling.String(), + StartTime: got.GetItem().GetUpdatedTime(), + }, + { + Status: session.StatusPending.String(), + StartTime: got.GetItem().GetCreatedTime(), + EndTime: got.GetItem().GetUpdatedTime(), + }, + } + assert.Empty(cmp.Diff(got.GetItem().GetStates(), wantState, protocmp.Transform()), "GetSession(%q) states") + got.GetItem().States = nil + got.GetItem().UpdatedTime = nil + + assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "GetSession(%q) got response\n%q, wanted\n%q", tc.req, got, tc.res) + + if tc.req != nil { + require.NotNil(got) + version = got.GetItem().GetVersion() + } + }) + } +} diff --git a/internal/session/session.go b/internal/session/session.go index f6db63a56..8de29b371 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -149,6 +149,13 @@ func (s *Session) Clone() interface{} { Endpoint: s.Endpoint, ConnectionLimit: s.ConnectionLimit, } + if len(s.States) > 0 { + clone.States = make([]*State, 0, len(s.States)) + for _, ss := range s.States { + cp := ss.Clone().(*State) + clone.States = append(clone.States, cp) + } + } if s.TofuToken != nil { clone.TofuToken = make([]byte, len(s.TofuToken)) copy(clone.TofuToken, s.TofuToken) diff --git a/internal/session/testing.go b/internal/session/testing.go index fefcde304..6dd6b92f0 100644 --- a/internal/session/testing.go +++ b/internal/session/testing.go @@ -72,6 +72,11 @@ func TestState(t *testing.T, conn *gorm.DB, sessionId string, state Status) *Sta func TestSession(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, c ComposedOf, opt ...Option) *Session { t.Helper() require := require.New(t) + if c.ExpirationTime == nil { + future, err := ptypes.TimestampProto(time.Now().Add(time.Hour)) + require.NoError(err) + c.ExpirationTime = ×tamp.Timestamp{Timestamp: future} + } rw := db.New(conn) s, err := New(c, opt...) require.NoError(err) @@ -81,8 +86,17 @@ func TestSession(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, c Compos _, certBytes, err := newCert(wrapper, c.UserId, id, c.ExpirationTime.Timestamp.AsTime()) require.NoError(err) s.Certificate = certBytes + + if len(s.TofuToken) != 0 { + err = s.encrypt(context.Background(), wrapper) + } + require.NoError(err) err = rw.Create(context.Background(), s) require.NoError(err) + ss, err := fetchStates(context.Background(), rw, s.PublicId, db.WithOrder("start_time desc")) + require.NoError(err) + s.States = ss + return s } diff --git a/internal/types/action/action.go b/internal/types/action/action.go index afdf914a2..5531ec31d 100644 --- a/internal/types/action/action.go +++ b/internal/types/action/action.go @@ -33,6 +33,7 @@ const ( AddHostSets Type = 24 SetHostSets Type = 25 RemoveHostSets Type = 26 + Cancel Type = 27 ) var Map = map[string]Type{ @@ -62,6 +63,7 @@ var Map = map[string]Type{ AddHostSets.String(): AddHostSets, SetHostSets.String(): SetHostSets, RemoveHostSets.String(): RemoveHostSets, + Cancel.String(): Cancel, } func (a Type) String() string { @@ -93,5 +95,6 @@ func (a Type) String() string { "add-host-sets", "set-host-sets", "remove-host-sets", + "cancel", }[a] } diff --git a/internal/types/resource/resource.go b/internal/types/resource/resource.go index 49c02937d..9cde3413f 100644 --- a/internal/types/resource/resource.go +++ b/internal/types/resource/resource.go @@ -19,6 +19,7 @@ const ( Target Type = 12 Controller Type = 13 Worker Type = 14 + Session Type = 15 ) func (r Type) String() string {