diff --git a/api/client.go b/api/client.go index c002f1e53..905b27aa4 100644 --- a/api/client.go +++ b/api/client.go @@ -58,11 +58,12 @@ type Config struct { // per-call, regardless of any value set in Token. RecoveryKmsWrapper wrapping.Wrapper - // HttpClient is the HTTP client to use. Boundary sets sane defaults for - // the http.Client and its associated http.Transport created in - // DefaultConfig. If you must modify Boundary's defaults, it is - // suggested that you start with that client and modify as needed rather - // than start with an empty client (or http.DefaultClient). + // HttpClient is the HTTP client to use. Boundary sets sane defaults for the + // http.Client and its associated http.Transport created in DefaultConfig. + // If you must modify Boundary's defaults, it is suggested that you start + // with that client and modify as needed rather than start with an empty + // client (or http.DefaultClient). Currently if the client is cloned the + // same HttpClient is used. HttpClient *http.Client // TLSConfig contains TLS configuration information. After modifying these @@ -86,19 +87,16 @@ type Config struct { // The CheckRetry function to use; a default is used if not provided CheckRetry retryablehttp.CheckRetry - // Limiter is the rate limiter used by the client. - // If this pointer is nil, then there will be no limit set. - // In contrast, if this pointer is set, even to an empty struct, - // then that limiter will be used. Note that an empty Limiter - // is equivalent blocking all events. + // Limiter is the rate limiter used by the client. If this pointer is nil, + // then there will be no limit set. In contrast, if this pointer is set, + // even to an empty struct, then that limiter will be used. Note that an + // empty Limiter is equivalent blocking all events. Currently if the client + // is cloned the same limiter is used. Limiter *rate.Limiter // OutputCurlString causes the actual request to return an error of type // *OutputStringError. Type asserting the error message will allow // fetching a cURL-compatible string for the operation. - // - // Note: It is not thread-safe to set this and make concurrent requests - // with the same client. Cloning a client will not clone this value. OutputCurlString bool // SRVLookup enables the client to lookup the host through DNS SRV lookup @@ -561,6 +559,7 @@ func (c *Client) Clone() *Client { Backoff: config.Backoff, CheckRetry: config.CheckRetry, Limiter: config.Limiter, + OutputCurlString: config.OutputCurlString, SRVLookup: config.SRVLookup, } if config.TLSConfig != nil { diff --git a/api/internal/genapi/input.go b/api/internal/genapi/input.go index 298b9c047..93ec85b19 100644 --- a/api/internal/genapi/input.go +++ b/api/internal/genapi/input.go @@ -31,6 +31,7 @@ type fieldInfo struct { GenerateSdkOption bool SubtypeName string Query bool + SkipDefault bool } type structInfo struct { @@ -338,6 +339,14 @@ var inputStructs = []*structInfo{ sliceSubTypes: map[string]string{ "HostSets": "hostSetIds", }, + extraOptions: []fieldInfo{ + { + Name: "HostId", + ProtoName: "host_id", + FieldType: "string", + SkipDefault: true, + }, + }, versionEnabled: true, typeOnCreate: true, createResponseTypes: true, @@ -347,4 +356,14 @@ var inputStructs = []*structInfo{ outFile: "targets/tcp_target_attributes.gen.go", subtypeName: "TcpTarget", }, + { + inProto: &targets.SessionAuthorization{}, + outFile: "targets/session_authorization.gen.go", + subtypeName: "SessionAuthorization", + }, + { + inProto: &targets.WorkerInfo{}, + outFile: "targets/worker_info.gen.go", + subtypeName: "WorkerInfo", + }, } diff --git a/api/internal/genapi/parse.go b/api/internal/genapi/parse.go index 6eec971da..34ab5e94e 100644 --- a/api/internal/genapi/parse.go +++ b/api/internal/genapi/parse.go @@ -62,6 +62,8 @@ func parsePBs() { name = fmt.Sprintf("%s.%s", pkg, name) } fi.FieldType = sliceText + ptr + name + case protoreflect.BytesKind: + fi.FieldType = "[]byte" default: fi.FieldType = sliceText + k.String() } diff --git a/api/internal/genapi/templates.go b/api/internal/genapi/templates.go index 486a3c9a7..c008166cc 100644 --- a/api/internal/genapi/templates.go +++ b/api/internal/genapi/templates.go @@ -728,7 +728,7 @@ func With{{ .SubtypeName }}{{ .Name }}(in{{ .Name }} {{ .FieldType }}) Option { o.postMap["{{ .ProtoName }}"] = in{{ .Name }} {{ end }} } } - +{{ if ( not .SkipDefault ) }} func Default{{ .SubtypeName }}{{ .Name }}() Option { return func(o *options) { {{ if ( not ( eq .SubtypeName "" ) ) }} raw, ok := o.postMap["attributes"] @@ -743,6 +743,7 @@ func Default{{ .SubtypeName }}{{ .Name }}() Option { {{ end }} } } {{ end }} +{{ end }} `)) func makeSlice(strs ...string) []string { diff --git a/api/targets/custom.go b/api/targets/custom.go new file mode 100644 index 000000000..084a7fcc4 --- /dev/null +++ b/api/targets/custom.go @@ -0,0 +1,71 @@ +package targets + +import ( + "bytes" + "context" + "fmt" + "net/url" + + "github.com/hashicorp/boundary/api" +) + +type SessionAuthorizationResult struct { + Item *SessionAuthorization + responseBody *bytes.Buffer + responseMap map[string]interface{} +} + +func (n SessionAuthorizationResult) GetItem() interface{} { + return n.Item +} + +func (n SessionAuthorizationResult) GetResponseBody() *bytes.Buffer { + return n.responseBody +} + +func (n SessionAuthorizationResult) GetResponseMap() map[string]interface{} { + return n.responseMap +} + +func (c *Client) Authorize(ctx context.Context, targetId string, opt ...Option) (*SessionAuthorizationResult, *api.Error, error) { + if targetId == "" { + return nil, nil, fmt.Errorf("empty targetId value passed into Authorize request") + } + + opts, apiOpts := getOpts(opt...) + + if c.client == nil { + return nil, nil, fmt.Errorf("nil client") + } + + req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("targets/%s:authorize", targetId), opts.postMap, apiOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error creating Authorize 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 Authorize call: %w", err) + } + + sar := new(SessionAuthorizationResult) + sar.Item = new(SessionAuthorization) + apiErr, err := resp.Decode(sar.Item) + if err != nil { + return nil, nil, fmt.Errorf("error decoding Authorize response: %w", err) + } + if apiErr != nil { + return nil, apiErr, nil + } + sar.responseBody = resp.Body + sar.responseMap = resp.Map + return sar, apiErr, nil +} diff --git a/api/targets/option.gen.go b/api/targets/option.gen.go index 1733b7040..ea198ecde 100644 --- a/api/targets/option.gen.go +++ b/api/targets/option.gen.go @@ -93,6 +93,12 @@ func DefaultDescription() Option { } } +func WithHostId(inHostId string) Option { + return func(o *options) { + o.postMap["host_id"] = inHostId + } +} + func WithName(inName string) Option { return func(o *options) { o.postMap["name"] = inName diff --git a/api/targets/session_authorization.gen.go b/api/targets/session_authorization.gen.go new file mode 100644 index 000000000..0f7ffdf4b --- /dev/null +++ b/api/targets/session_authorization.gen.go @@ -0,0 +1,17 @@ +// Code generated by "make api"; DO NOT EDIT. +package targets + +import ( + "time" + + "github.com/hashicorp/boundary/api/scopes" +) + +type SessionAuthorization struct { + SessionId string `json:"session_id,omitempty"` + TargetId string `json:"target_id,omitempty"` + Scope *scopes.ScopeInfo `json:"scope,omitempty"` + CreatedTime time.Time `json:"created_time,omitempty"` + Type string `json:"type,omitempty"` + AuthorizationToken string `json:"authorization_token,omitempty"` +} diff --git a/api/targets/worker_info.gen.go b/api/targets/worker_info.gen.go new file mode 100644 index 000000000..df00afeb1 --- /dev/null +++ b/api/targets/worker_info.gen.go @@ -0,0 +1,6 @@ +// Code generated by "make api"; DO NOT EDIT. +package targets + +type WorkerInfo struct { + Address string `json:"address,omitempty"` +} diff --git a/cmd/boundary/main.go b/cmd/boundary/main.go index 510ab7d08..4f2bcb3ad 100644 --- a/cmd/boundary/main.go +++ b/cmd/boundary/main.go @@ -1,11 +1,14 @@ package main import ( + "math/rand" "os" + "time" "github.com/hashicorp/boundary/internal/cmd" ) func main() { + rand.Seed(time.Now().UnixNano()) os.Exit(cmd.Run(os.Args[1:])) } diff --git a/internal/auth/auth.go b/internal/auth/auth.go index ae42d5060..cf9e7930d 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -63,9 +63,10 @@ type RequestInfo struct { } type VerifyResults struct { - UserId string - Error error - Scope *scopes.ScopeInfo + UserId string + AuthTokenId string + Error error + Scope *scopes.ScopeInfo } type verifier struct { @@ -160,6 +161,7 @@ func Verify(ctx context.Context, opt ...Option) (ret VerifyResults) { v.logger.Error("error performing authn/authz check", "error", err) return } + ret.AuthTokenId = v.requestInfo.PublicId if !authResults.Allowed { if v.requestInfo.DisableAuthzFailures { ret.Error = nil diff --git a/internal/cmd/base/base.go b/internal/cmd/base/base.go index 14aa7d64d..bba25a08e 100644 --- a/internal/cmd/base/base.go +++ b/internal/cmd/base/base.go @@ -362,8 +362,7 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets { f.BoolVar(&BoolVar{ Name: "output-curl-string", Target: &c.flagOutputCurlString, - Usage: "Instead of executing the request, print an equivalent cURL " + - "command string and exit.", + Usage: "Instead of executing the request, print an equivalent cURL command string and exit.", }) } @@ -386,8 +385,7 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets { Default: "table", EnvVar: EnvBoundaryCLIFormat, Completion: complete.PredictSet("table", "json", "yaml"), - Usage: "Print the output in the given format. Valid formats " + - "are \"table\", \"json\", or \"yaml\".", + Usage: "Print the output in the given format. Valid formats are \"table\" or \"json\".", }) } } diff --git a/internal/cmd/commands.go b/internal/cmd/commands.go index 752e8bef2..63756d3db 100644 --- a/internal/cmd/commands.go +++ b/internal/cmd/commands.go @@ -65,6 +65,13 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) { "proxy": func() (cli.Command, error) { return &proxy.Command{ Command: base.NewCommand(ui), + Func: "proxy", + }, nil + }, + "connect": func() (cli.Command, error) { + return &proxy.Command{ + Command: base.NewCommand(ui), + Func: "connect", }, nil }, @@ -558,6 +565,12 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) { Command: base.NewCommand(ui), }, nil }, + "targets authorize": func() (cli.Command, error) { + return &targets.Command{ + Command: base.NewCommand(ui), + Func: "authorize", + }, nil + }, "targets read": func() (cli.Command, error) { return &targets.Command{ Command: base.NewCommand(ui), diff --git a/internal/cmd/commands/proxy/funcs.go b/internal/cmd/commands/proxy/funcs.go new file mode 100644 index 000000000..e447535b9 --- /dev/null +++ b/internal/cmd/commands/proxy/funcs.go @@ -0,0 +1,31 @@ +package proxy + +import ( + "github.com/hashicorp/boundary/internal/cmd/base" +) + +func generateConnectionInfoTableOutput(in ConnectionInfo) string { + var ret []string + + nonAttributeMap := map[string]interface{}{ + "Protocol": in.Protocol, + "Address": in.Address, + "Port": in.Port, + } + + maxLength := 0 + for k := range nonAttributeMap { + if len(k) > maxLength { + maxLength = len(k) + } + } + + ret = append(ret, "", "Proxy listening information:") + + ret = append(ret, + // We do +2 because there is another +2 offset for host sets below + base.WrapMap(2, maxLength+2, nonAttributeMap), + ) + + return base.WrapForHelpText(ret) +} diff --git a/internal/cmd/commands/proxy/proxy.go b/internal/cmd/commands/proxy/proxy.go index 705a2e5fd..e0359b598 100644 --- a/internal/cmd/commands/proxy/proxy.go +++ b/internal/cmd/commands/proxy/proxy.go @@ -4,6 +4,7 @@ import ( "crypto/ed25519" "crypto/tls" "crypto/x509" + "encoding/json" "fmt" "io" "io/ioutil" @@ -15,60 +16,109 @@ import ( "github.com/btcsuite/btcutil/base58" "github.com/golang/protobuf/proto" + "github.com/hashicorp/boundary/api/targets" "github.com/hashicorp/boundary/globals" "github.com/hashicorp/boundary/internal/cmd/base" - wpbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" + targetspb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" "github.com/hashicorp/boundary/internal/proxy" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/vault/sdk/helper/base62" + "github.com/kr/pretty" "github.com/mitchellh/cli" "github.com/posener/complete" "nhooyr.io/websocket" "nhooyr.io/websocket/wspb" ) +type ConnectionInfo struct { + Address string `json:"address"` + Port int `json:"port"` + Protocol string `json:"protocol"` +} + var _ cli.Command = (*Command)(nil) var _ cli.CommandAutocomplete = (*Command)(nil) type Command struct { *base.Command - flagAuth string + flagAuthz string flagListenAddr string flagListenPort int flagVerbose bool + flagTargetId string + flagHostId string + + Func string } func (c *Command) Synopsis() string { - return "Launch the Boundary CLI in proxy mode" + switch c.Func { + case "proxy": + return "Launch the Boundary CLI in proxy mode" + case "connect": + return "Authorize a session against a target and launch a proxied connection" + } + return "" } func (c *Command) Help() string { - return base.WrapForHelpText([]string{ - "Usage: boundary proxy [options] [args]", - "", - " This command allows launching the Boundary CLI in proxy mode. In this mode, the CLI expects to take in an authorization string returned from a Boundary controller. The CLI will then create a connection to a Boundary worker and ready a listening port for a local connection.", - "", - " Example:", - "", - ` $ boundary proxy -auth "UgxzX29mVEpwNUt6QlGiAQ..."`, - "", - " Please see the {{type}}s subcommand help for detailed usage information.", - }) + c.Flags().Help() + switch c.Func { + case "proxy": + return base.WrapForHelpText([]string{ + "Usage: boundary proxy [options] [args]", + "", + " This command allows launching the Boundary CLI in proxy mode. In this mode, the CLI expects to take in an authorization string returned from a Boundary controller. The CLI will then create a connection to a Boundary worker and ready a listening port for a local connection.", + "", + " Example:", + "", + ` $ boundary proxy -auth "UgxzX29mVEpwNUt6QlGiAQ..."`, + }) + c.Flags().Help() + + case "connect": + return base.WrapForHelpText([]string{ + "Usage: boundary connect [options] [args]", + "", + ` This command performs a target authorization and proxy launch in one command; it is equivalent to sending the output of "boundary targets authorize" into "boundary proxy". See the help output for those commands for more information.`, + "", + " Example:", + "", + ` $ boundary connect -target-id ttcp_1234567890"`, + }) + c.Flags().Help() + } + return "" } func (c *Command) Flags() *base.FlagSets { - set := c.FlagSet(0) + bits := base.FlagSetOutputFormat + if c.Func == "connect" { + bits = base.FlagSetHTTP | base.FlagSetClient | bits + } + set := c.FlagSet(bits) f := set.NewFlagSet("Proxy Options") - f.StringVar(&base.StringVar{ - Name: "auth", - Target: &c.flagAuth, - EnvVar: "BOUNDARY_PROXY_AUTH", - Completion: complete.PredictAnything, - Usage: `The authorization string returned from the Boundary controller. If set to "-", the command will attempt to read in the authorization string from standard input.`, - }) + switch c.Func { + case "proxy": + f.StringVar(&base.StringVar{ + Name: "authz", + Target: &c.flagAuthz, + EnvVar: "BOUNDARY_PROXY_AUTHZ", + Completion: complete.PredictAnything, + Usage: `The authorization string returned from the Boundary controller. If set to "-", the command will attempt to read in the authorization string from standard input.`, + }) + case "connect": + f.StringVar(&base.StringVar{ + Name: "target-id", + Target: &c.flagTargetId, + Usage: "The ID of the target to authorize against.", + }) + f.StringVar(&base.StringVar{ + Name: "host-id", + Target: &c.flagHostId, + Usage: "The ID of a specific host to connect to out of the hosts from the target's host sets. If not specified, one is chosen at random.", + }) + } f.StringVar(&base.StringVar{ Name: "listen-addr", @@ -112,7 +162,7 @@ func (c *Command) Run(args []string) int { return 1 } - var handshake proxy.Handshake + var handshake proxy.ClientHandshake var err error if handshake.TofuToken, err = base62.Random(20); err != nil { c.UI.Error(fmt.Errorf("Could not derive random bytes for tofu token: %w", err).Error()) @@ -128,38 +178,85 @@ func (c *Command) Run(args []string) int { return 1 } - if c.flagAuth == "-" { - authBytes, err := ioutil.ReadAll(os.Stdin) + authzString := c.flagAuthz + switch c.Func { + case "proxy": + if authzString == "-" { + authBytes, err := ioutil.ReadAll(os.Stdin) + if err != nil { + c.UI.Error(fmt.Errorf("No authorization string was provided and encountered the following error attempting to read it from stdin: %w", err).Error()) + return 1 + } + if len(authBytes) == 0 { + c.UI.Error("No authorization data read from stdin") + return 1 + } + authzString = string(authBytes) + } + + if authzString == "" { + c.UI.Error("Authorization data was empty") + return 1 + } + + if authzString[0] == '{' { + // Attempt to decode the JSON output of an authorize call and pull the + // token out of there + var sa targets.SessionAuthorization + if err := json.Unmarshal([]byte(authzString), &sa); err == nil { + authzString = sa.AuthorizationToken + } + } + + case "connect": + if c.flagTargetId == "" { + c.UI.Error("Target ID must be provided") + return 1 + } + + client, err := c.Client() if err != nil { - c.UI.Error(fmt.Errorf("No authorization string was provided and encountered the following error attempting to read it from stdin: %w", err).Error()) + c.UI.Error(fmt.Sprintf("Error creating API client: %s", err.Error())) + return 2 + } + targetClient := targets.NewClient(client) + + var opts []targets.Option + if len(c.flagHostId) != 0 { + opts = append(opts, targets.WithHostId(c.flagHostId)) + } + + sar, apiErr, err := targetClient.Authorize(c.Context, c.flagTargetId, opts...) + if err != nil { + c.UI.Error(fmt.Sprintf("Error trying to authorize a session against target: %s", err.Error())) + return 2 + } + if apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing authorize on a session against target: %s", pretty.Sprint(apiErr))) return 1 } - if len(authBytes) == 0 { - c.UI.Error("No authorization data read from stdin") - return 1 - } - c.flagAuth = string(authBytes) + sa := sar.GetItem().(*targets.SessionAuthorization) + authzString = sa.AuthorizationToken } - marshaled := base58.Decode(c.flagAuth) + marshaled := base58.Decode(authzString) if len(marshaled) == 0 { c.UI.Error("Zero length authorization information after decoding") return 1 } - sessionResponseInfo := new(wpbs.GetSessionResponse) - if err := proto.Unmarshal(marshaled, sessionResponseInfo); err != nil { - c.UI.Error(fmt.Errorf("Unable to proto-decode authorization string: %w", err).Error()) + data := new(targetspb.SessionAuthorizationData) + if err := proto.Unmarshal(marshaled, data); err != nil { + c.UI.Error(fmt.Errorf("Unable to proto-decode authorization data: %w", err).Error()) return 1 } - sessionInfo := sessionResponseInfo.GetSession() - if len(sessionInfo.GetWorkerInfo()) == 0 { + if len(data.GetWorkerInfo()) == 0 { c.UI.Error("No workers found in authorization string") return 1 } - parsedCert, err := x509.ParseCertificate(sessionInfo.Certificate) + parsedCert, err := x509.ParseCertificate(data.Certificate) if err != nil { c.UI.Error(fmt.Errorf("Unable to decode mTLS certificate: %w", err).Error()) return 1 @@ -176,8 +273,8 @@ func (c *Command) Run(args []string) int { tlsConf := &tls.Config{ Certificates: []tls.Certificate{ { - Certificate: [][]byte{sessionInfo.Certificate}, - PrivateKey: ed25519.PrivateKey(sessionInfo.PrivateKey), + Certificate: [][]byte{data.Certificate}, + PrivateKey: ed25519.PrivateKey(data.PrivateKey), Leaf: parsedCert, }, }, @@ -198,9 +295,8 @@ func (c *Command) Run(args []string) int { c.UI.Error(fmt.Errorf("Error starting listening port: %w", err).Error()) return 1 } - c.UI.Info(fmt.Sprintf("%s", listener.Addr().String())) - workerAddr := sessionInfo.GetWorkerInfo()[0].GetAddress() + workerAddr := data.GetWorkerInfo()[0].GetAddress() conn, resp, err := websocket.Dial( c.Context, @@ -239,9 +335,33 @@ func (c *Command) Run(args []string) int { } if err := wspb.Write(c.Context, conn, &handshake); err != nil { - c.UI.Error(fmt.Errorf("error sending tofu token to worker: %w", err).Error()) + c.UI.Error(fmt.Errorf("error sending handshake to worker: %w", err).Error()) return 1 } + var handshakeResult proxy.HandshakeResult + if err := wspb.Read(c.Context, conn, &handshakeResult); err != nil { + c.UI.Error(fmt.Errorf("error reading handshake result: %w", err).Error()) + return 1 + } + + listenerAddr := listener.Addr().(*net.TCPAddr) + connInfo := ConnectionInfo{ + Protocol: "tcp", + Address: listenerAddr.IP.String(), + Port: listenerAddr.Port, + } + + switch base.Format(c.UI) { + case "table": + c.UI.Output(generateConnectionInfoTableOutput(connInfo)) + case "json": + out, err := json.Marshal(&connInfo) + if err != nil { + c.UI.Error(fmt.Errorf("error marshaling connection information: %w", err).Error()) + return 1 + } + c.UI.Output(string(out)) + } // Get a wrapped net.Conn so we can use io.Copy netConn := websocket.NetConn(c.Context, conn, websocket.MessageBinary) diff --git a/internal/cmd/commands/targets/funcs.go b/internal/cmd/commands/targets/funcs.go index 888e00a2f..833b67603 100644 --- a/internal/cmd/commands/targets/funcs.go +++ b/internal/cmd/commands/targets/funcs.go @@ -94,6 +94,35 @@ func generateTargetTableOutput(in *targets.Target) string { return base.WrapForHelpText(ret) } +func generateAuthorizationTableOutput(in *targets.SessionAuthorization) string { + var ret []string + + nonAttributeMap := map[string]interface{}{ + "Session ID": in.SessionId, + "Target ID": in.TargetId, + "Scope ID": in.Scope.Id, + "Created Time": in.CreatedTime.Local().Format(time.RFC3339), + "Type": in.Type, + "Authorization Token": in.AuthorizationToken, + } + + maxLength := 0 + for k := range nonAttributeMap { + if len(k) > maxLength { + maxLength = len(k) + } + } + + ret = append(ret, "", "Target information:") + + ret = append(ret, + // We do +2 because there is another +2 offset for host sets below + base.WrapMap(2, maxLength+2, nonAttributeMap), + ) + + return base.WrapForHelpText(ret) +} + var attributeMap = map[string]string{ "default_port": "Default Port", } diff --git a/internal/cmd/commands/targets/target.go b/internal/cmd/commands/targets/target.go index a1285f6fc..c18d442b6 100644 --- a/internal/cmd/commands/targets/target.go +++ b/internal/cmd/commands/targets/target.go @@ -25,6 +25,7 @@ type Command struct { Func string flagHostSets []string + flagHostId string } func (c *Command) Synopsis() string { @@ -39,6 +40,7 @@ func (c *Command) Synopsis() string { } var flagsMap = map[string][]string{ + "authorize": {"id", "host-id"}, "read": {"id"}, "delete": {"id"}, "list": {"scope-id"}, @@ -89,7 +91,7 @@ func (c *Command) Help() string { }) case "add-host-sets": helpStr = base.WrapForHelpText([]string{ - "Usage: boundary target add-host-sets [sub command] [options] [args]", + "Usage: boundary target add-host-sets [options] [args]", "", " This command allows adding host-set resources to target resources. Example:", "", @@ -99,7 +101,7 @@ func (c *Command) Help() string { }) case "remove-host-sets": helpStr = base.WrapForHelpText([]string{ - "Usage: boundary target remove-host-sets [sub command] [options] [args]", + "Usage: boundary target remove-host-sets [options] [args]", "", " This command allows removing host-set resources from target resources. Example:", "", @@ -109,7 +111,7 @@ func (c *Command) Help() string { }) case "set-host-sets": helpStr = base.WrapForHelpText([]string{ - "Usage: boundary target set-host-sets [sub command] [options] [args]", + "Usage: boundary target set-host-sets [options] [args]", "", " This command allows setting the complete set of host-set resources on a target resource. Example:", "", @@ -117,6 +119,16 @@ func (c *Command) Help() string { "", ` $ boundary targets set-host-sets -id ttcp_1234567890 -host-set hsst_1234567890`, }) + case "authorize": + helpStr = base.WrapForHelpText([]string{ + "Usage: boundary target authorize [options] [args]", + "", + " This command allows fetching session authorization credentials against a target. Example:", + "", + " Set host-set resources on a tcp-type target:", + "", + ` $ boundary targets authorize -id ttcp_1234567890`, + }) default: helpStr = helpMap[c.Func]() } @@ -137,6 +149,12 @@ func (c *Command) Flags() *base.FlagSets { Target: &c.flagHostSets, Usage: "The host-set resources to add, remove, or set. May be specified multiple times.", }) + case "host-id": + f.StringVar(&base.StringVar{ + Name: "host-id", + Target: &c.flagHostId, + Usage: "The ID of a specific host to connect to out of the hosts from the target's host sets. If not specified, one is chosen at random.", + }) } } @@ -220,6 +238,10 @@ func (c *Command) Run(args []string) int { hostSets = nil } } + case "authorize": + if len(c.flagHostId) != 0 { + opts = append(opts, targets.WithHostId(c.flagHostId)) + } } // Perform check-and-set when needed @@ -243,6 +265,7 @@ func (c *Command) Run(args []string) int { var result api.GenericResult var listResult api.GenericListResult var apiErr *api.Error + var sar *targets.SessionAuthorizationResult switch c.Func { case "read": @@ -261,11 +284,16 @@ func (c *Command) Run(args []string) int { result, apiErr, err = targetClient.RemoveHostSets(c.Context, c.FlagId, version, hostSets, opts...) case "set-host-sets": result, apiErr, err = targetClient.SetHostSets(c.Context, c.FlagId, version, hostSets, opts...) + case "authorize": + sar, apiErr, err = targetClient.Authorize(c.Context, c.FlagId, opts...) } plural := "target" - if c.Func == "list" { + switch c.Func { + case "list": plural = "targets" + case "authorize": + plural = "a session against target" } if err != nil { c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) @@ -343,6 +371,21 @@ func (c *Command) Run(args []string) int { c.UI.Output(base.WrapForHelpText(output)) } return 0 + + case "authorize": + sa := sar.GetItem().(*targets.SessionAuthorization) + switch base.Format(c.UI) { + case "table": + c.UI.Output(generateAuthorizationTableOutput(sa)) + case "json": + b, err := base.JsonFormatter{}.Format(sa) + if err != nil { + c.UI.Error(fmt.Errorf("Error formatting as JSON: %w", err).Error()) + return 1 + } + c.UI.Output(string(b)) + } + return 0 } target := result.GetItem().(*targets.Target) diff --git a/internal/cmd/main.go b/internal/cmd/main.go index 578996140..1c6161f8a 100644 --- a/internal/cmd/main.go +++ b/internal/cmd/main.go @@ -183,7 +183,7 @@ func RunCustom(args []string, runOpts *RunOptions) int { fmt.Fprint(runOpts.Stderr, "cURL command not set by API operation; run without -output-curl-string to see the generated error\n") return exitCode } - if api.LastOutputStringError.Error() != api.ErrOutputStringRequest { + if !strings.Contains(api.LastOutputStringError.Error(), api.ErrOutputStringRequest) { runOpts.Stdout.Write([]byte(fmt.Sprintf("Error creating request string: %s\n", api.LastOutputStringError.Error()))) return 1 } diff --git a/internal/db/migrations/postgres.gen.go b/internal/db/migrations/postgres.gen.go index 4132864ef..ac9c8942b 100644 --- a/internal/db/migrations/postgres.gen.go +++ b/internal/db/migrations/postgres.gen.go @@ -3427,14 +3427,15 @@ begin; on update cascade, version wt_version, create_time wt_timestamp, - update_time wt_timestamp + update_time wt_timestamp, + endpoint text -- not part of the warehouse, used to send info to the worker ); create trigger immutable_columns before update on session - for each row execute procedure immutable_columns('public_id', 'certificate', 'expiration_time', 'connection_limit', 'create_time'); + for each row execute procedure immutable_columns('public_id', 'certificate', 'expiration_time', 'connection_limit', 'create_time', 'endpoint'); create trigger update_version_column @@ -3470,6 +3471,8 @@ begin; raise exception 'auth_token_id is null'; when new.scope_id is null then raise exception 'scope_id is null'; + when new.endpoint is null then + raise exception 'endpoint is null'; else end case; return new; diff --git a/internal/db/migrations/postgres/50_session.up.sql b/internal/db/migrations/postgres/50_session.up.sql index 81c41db8e..bbe164f09 100644 --- a/internal/db/migrations/postgres/50_session.up.sql +++ b/internal/db/migrations/postgres/50_session.up.sql @@ -151,14 +151,15 @@ begin; on update cascade, version wt_version, create_time wt_timestamp, - update_time wt_timestamp + update_time wt_timestamp, + endpoint text -- not part of the warehouse, used to send info to the worker ); create trigger immutable_columns before update on session - for each row execute procedure immutable_columns('public_id', 'certificate', 'expiration_time', 'connection_limit', 'create_time'); + for each row execute procedure immutable_columns('public_id', 'certificate', 'expiration_time', 'connection_limit', 'create_time', 'endpoint'); create trigger update_version_column @@ -194,6 +195,8 @@ begin; raise exception 'auth_token_id is null'; when new.scope_id is null then raise exception 'scope_id is null'; + when new.endpoint is null then + raise exception 'endpoint is null'; else end case; return new; diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json index 3269e7e66..d2e1226a9 100644 --- a/internal/gen/controller.swagger.json +++ b/internal/gen/controller.swagger.json @@ -1999,6 +1999,39 @@ ] } }, + "/v1/targets/{id}:authorize": { + "post": { + "summary": "Authorizes a Session", + "operationId": "TargetService_AuthorizeSession", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.targets.v1.SessionAuthorization" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.AuthorizeSessionRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.TargetService" + ] + } + }, "/v1/targets/{id}:remove-host-sets": { "post": { "summary": "Removes Host Sets from the Target.", @@ -2014,7 +2047,6 @@ "parameters": [ { "name": "id", - "description": "This host set's id.", "in": "path", "required": true, "type": "string" @@ -2876,6 +2908,42 @@ } } }, + "controller.api.resources.targets.v1.SessionAuthorization": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "description": "The ID of the session\nOutput only.", + "readOnly": true + }, + "target_id": { + "type": "string", + "description": "The id of the target authorizing this session. This must be defined for\ncreation of this resource, but is otherwise read only.\nOutput only.", + "readOnly": true + }, + "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 + }, + "type": { + "type": "string", + "description": "Type of the session (e.g. tcp, ssh, etc.)\nOutput only.", + "readOnly": true + }, + "authorization_token": { + "type": "string", + "description": "The marshaled SessionAuthorizationData message containing all information\nthat the proxy needs.\nOutput only.", + "readOnly": true + } + } + }, "controller.api.resources.targets.v1.Target": { "type": "object", "properties": { @@ -3152,6 +3220,26 @@ } } }, + "controller.api.services.v1.AuthorizeSessionRequest": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "host_id": { + "type": "string", + "description": "An optional parameter allowing specification of the particular host within\nthe target's host sets to connect to during this session." + } + } + }, + "controller.api.services.v1.AuthorizeSessionResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.targets.v1.SessionAuthorization" + } + } + }, "controller.api.services.v1.ChangePasswordRequest": { "type": "object", "properties": { @@ -3643,8 +3731,7 @@ "type": "object", "properties": { "id": { - "type": "string", - "description": "This host set's id." + "type": "string" }, "version": { "type": "integer", diff --git a/internal/gen/controller/api/resources/sessions/session.pb.go b/internal/gen/controller/api/resources/sessions/session.pb.go index 65dc67f8a..4c19eaa08 100644 --- a/internal/gen/controller/api/resources/sessions/session.pb.go +++ b/internal/gen/controller/api/resources/sessions/session.pb.go @@ -12,6 +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/protooptions" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -30,54 +31,6 @@ 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 "" -} - // Session contains all fields related to a Session resource type Session struct { state protoimpl.MessageState @@ -118,13 +71,13 @@ type Session struct { 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 []*WorkerInfo `protobuf:"bytes,150,rep,name=worker_info,proto3" json:"worker_info,omitempty"` + WorkerInfo []*targets.WorkerInfo `protobuf:"bytes,150,rep,name=worker_info,proto3" json:"worker_info,omitempty"` } func (x *Session) Reset() { *x = Session{} if protoimpl.UnsafeEnabled { - mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[1] + mi := &file_controller_api_resources_sessions_v1_session_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -137,7 +90,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[1] + 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 { @@ -150,7 +103,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{1} + return file_controller_api_resources_sessions_v1_session_proto_rawDescGZIP(), []int{0} } func (x *Session) GetId() string { @@ -251,7 +204,7 @@ func (x *Session) GetEndpoint() string { return "" } -func (x *Session) GetWorkerInfo() []*WorkerInfo { +func (x *Session) GetWorkerInfo() []*targets.WorkerInfo { if x != nil { return x.WorkerInfo } @@ -275,58 +228,59 @@ var file_controller_api_resources_sessions_v1_session_proto_rawDesc = []byte{ 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 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, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, - 0x6f, 0x70, 0x65, 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, 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, 0xf7, 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, 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, 0x53, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x96, 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, + 0x6f, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 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, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 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, + 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, + 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, } var ( @@ -341,19 +295,19 @@ 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, 2) +var file_controller_api_resources_sessions_v1_session_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_controller_api_resources_sessions_v1_session_proto_goTypes = []interface{}{ - (*WorkerInfo)(nil), // 0: controller.api.resources.sessions.v1.WorkerInfo - (*Session)(nil), // 1: controller.api.resources.sessions.v1.Session - (*scopes.ScopeInfo)(nil), // 2: controller.api.resources.scopes.v1.ScopeInfo - (*timestamp.Timestamp)(nil), // 3: google.protobuf.Timestamp + (*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 } var file_controller_api_resources_sessions_v1_session_proto_depIdxs = []int32{ - 2, // 0: controller.api.resources.sessions.v1.Session.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo - 3, // 1: controller.api.resources.sessions.v1.Session.created_time:type_name -> google.protobuf.Timestamp - 3, // 2: controller.api.resources.sessions.v1.Session.updated_time:type_name -> google.protobuf.Timestamp - 3, // 3: controller.api.resources.sessions.v1.Session.expiration_time:type_name -> google.protobuf.Timestamp - 0, // 4: controller.api.resources.sessions.v1.Session.worker_info:type_name -> controller.api.resources.sessions.v1.WorkerInfo + 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 @@ -368,18 +322,6 @@ 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.(*Session); i { case 0: return &v.state @@ -398,7 +340,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: 2, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/gen/controller/api/resources/targets/target.pb.go b/internal/gen/controller/api/resources/targets/target.pb.go index 34a5c1008..b54417eab 100644 --- a/internal/gen/controller/api/resources/targets/target.pb.go +++ b/internal/gen/controller/api/resources/targets/target.pb.go @@ -286,6 +286,283 @@ func (x *TcpTargetAttributes) GetDefaultPort() *wrappers.UInt32Value { return nil } +// WorkerInfo contains information about workers, returned in +// SessionAuthorization +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_targets_v1_target_proto_msgTypes[3] + 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_targets_v1_target_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 WorkerInfo.ProtoReflect.Descriptor instead. +func (*WorkerInfo) Descriptor() ([]byte, []int) { + return file_controller_api_resources_targets_v1_target_proto_rawDescGZIP(), []int{3} +} + +func (x *WorkerInfo) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +// SessionAuthorization contains all fields related to authorization for a +// session. It's in the Targets API because it's returned by a target authorize +// action. +type SessionAuthorizationData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The ID of the session + // Output only. + SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // The id of the target authorizing this session. This must be defined for + // creation of this resource, but is otherwise read only. + // Output only. + TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty"` + // Scope information for this resource + // Output only. + Scope *scopes.ScopeInfo `protobuf:"bytes,30,opt,name=scope,proto3" json:"scope,omitempty"` + // The time this resource was created + // Output only. + CreatedTime *timestamp.Timestamp `protobuf:"bytes,40,opt,name=created_time,proto3" json:"created_time,omitempty"` + // Type of the session (e.g. tcp, ssh, etc.) + // Output only. + Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty"` + // The certificate to use when connecting (or if using custom certs, to + // serve as the "login"). Raw DER bytes. + // Output only. + Certificate []byte `protobuf:"bytes,120,opt,name=certificate,proto3" json:"certificate,omitempty"` + // The private key to use when connecting (or if using custom certs, to pass + // as the "password"). We are using Ed25519 so this is purely raw bytes, no + // marshaling. + // Output only. + PrivateKey []byte `protobuf:"bytes,130,opt,name=private_key,proto3" json:"private_key,omitempty"` + // Worker information. The first worker in the array should be prioritized. + // Output only. + WorkerInfo []*WorkerInfo `protobuf:"bytes,150,rep,name=worker_info,proto3" json:"worker_info,omitempty"` +} + +func (x *SessionAuthorizationData) Reset() { + *x = SessionAuthorizationData{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_resources_targets_v1_target_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionAuthorizationData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionAuthorizationData) ProtoMessage() {} + +func (x *SessionAuthorizationData) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_resources_targets_v1_target_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 SessionAuthorizationData.ProtoReflect.Descriptor instead. +func (*SessionAuthorizationData) Descriptor() ([]byte, []int) { + return file_controller_api_resources_targets_v1_target_proto_rawDescGZIP(), []int{4} +} + +func (x *SessionAuthorizationData) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *SessionAuthorizationData) GetTargetId() string { + if x != nil { + return x.TargetId + } + return "" +} + +func (x *SessionAuthorizationData) GetScope() *scopes.ScopeInfo { + if x != nil { + return x.Scope + } + return nil +} + +func (x *SessionAuthorizationData) GetCreatedTime() *timestamp.Timestamp { + if x != nil { + return x.CreatedTime + } + return nil +} + +func (x *SessionAuthorizationData) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *SessionAuthorizationData) GetCertificate() []byte { + if x != nil { + return x.Certificate + } + return nil +} + +func (x *SessionAuthorizationData) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey + } + return nil +} + +func (x *SessionAuthorizationData) GetWorkerInfo() []*WorkerInfo { + if x != nil { + return x.WorkerInfo + } + return nil +} + +type SessionAuthorization struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The ID of the session + // Output only. + SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // The id of the target authorizing this session. This must be defined for + // creation of this resource, but is otherwise read only. + // Output only. + TargetId string `protobuf:"bytes,20,opt,name=target_id,proto3" json:"target_id,omitempty"` + // Scope information for this resource + // Output only. + Scope *scopes.ScopeInfo `protobuf:"bytes,30,opt,name=scope,proto3" json:"scope,omitempty"` + // The time this resource was created + // Output only. + CreatedTime *timestamp.Timestamp `protobuf:"bytes,40,opt,name=created_time,proto3" json:"created_time,omitempty"` + // Type of the session (e.g. tcp, ssh, etc.) + // Output only. + Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty"` + // The marshaled SessionAuthorizationData message containing all information + // that the proxy needs. + // Output only. + AuthorizationToken string `protobuf:"bytes,90,opt,name=authorization_token,json=authorizationToken,proto3" json:"authorization_token,omitempty"` +} + +func (x *SessionAuthorization) Reset() { + *x = SessionAuthorization{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_resources_targets_v1_target_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionAuthorization) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionAuthorization) ProtoMessage() {} + +func (x *SessionAuthorization) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_resources_targets_v1_target_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 SessionAuthorization.ProtoReflect.Descriptor instead. +func (*SessionAuthorization) Descriptor() ([]byte, []int) { + return file_controller_api_resources_targets_v1_target_proto_rawDescGZIP(), []int{5} +} + +func (x *SessionAuthorization) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *SessionAuthorization) GetTargetId() string { + if x != nil { + return x.TargetId + } + return "" +} + +func (x *SessionAuthorization) GetScope() *scopes.ScopeInfo { + if x != nil { + return x.Scope + } + return nil +} + +func (x *SessionAuthorization) GetCreatedTime() *timestamp.Timestamp { + if x != nil { + return x.CreatedTime + } + return nil +} + +func (x *SessionAuthorization) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *SessionAuthorization) GetAuthorizationToken() string { + if x != nil { + return x.AuthorizationToken + } + return "" +} + var File_controller_api_resources_targets_v1_target_proto protoreflect.FileDescriptor var file_controller_api_resources_targets_v1_target_proto_rawDesc = []byte{ @@ -359,12 +636,58 @@ var file_controller_api_resources_targets_v1_target_proto_rawDesc = []byte{ 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x0b, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x6f, 0x72, 0x74, - 0x42, 0x55, 0x5a, 0x53, 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, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x3b, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 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, 0x89, 0x03, 0x0a, 0x18, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x49, 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, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x50, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 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, 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, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x9d, 0x02, 0x0a, 0x14, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, + 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 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, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x55, 0x5a, 0x53, 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, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x73, 0x3b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -379,31 +702,39 @@ func file_controller_api_resources_targets_v1_target_proto_rawDescGZIP() []byte return file_controller_api_resources_targets_v1_target_proto_rawDescData } -var file_controller_api_resources_targets_v1_target_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_controller_api_resources_targets_v1_target_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_controller_api_resources_targets_v1_target_proto_goTypes = []interface{}{ - (*HostSet)(nil), // 0: controller.api.resources.targets.v1.HostSet - (*Target)(nil), // 1: controller.api.resources.targets.v1.Target - (*TcpTargetAttributes)(nil), // 2: controller.api.resources.targets.v1.TcpTargetAttributes - (*scopes.ScopeInfo)(nil), // 3: controller.api.resources.scopes.v1.ScopeInfo - (*wrappers.StringValue)(nil), // 4: google.protobuf.StringValue - (*timestamp.Timestamp)(nil), // 5: google.protobuf.Timestamp - (*_struct.Struct)(nil), // 6: google.protobuf.Struct - (*wrappers.UInt32Value)(nil), // 7: google.protobuf.UInt32Value + (*HostSet)(nil), // 0: controller.api.resources.targets.v1.HostSet + (*Target)(nil), // 1: controller.api.resources.targets.v1.Target + (*TcpTargetAttributes)(nil), // 2: controller.api.resources.targets.v1.TcpTargetAttributes + (*WorkerInfo)(nil), // 3: controller.api.resources.targets.v1.WorkerInfo + (*SessionAuthorizationData)(nil), // 4: controller.api.resources.targets.v1.SessionAuthorizationData + (*SessionAuthorization)(nil), // 5: controller.api.resources.targets.v1.SessionAuthorization + (*scopes.ScopeInfo)(nil), // 6: controller.api.resources.scopes.v1.ScopeInfo + (*wrappers.StringValue)(nil), // 7: google.protobuf.StringValue + (*timestamp.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*_struct.Struct)(nil), // 9: google.protobuf.Struct + (*wrappers.UInt32Value)(nil), // 10: google.protobuf.UInt32Value } var file_controller_api_resources_targets_v1_target_proto_depIdxs = []int32{ - 3, // 0: controller.api.resources.targets.v1.Target.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo - 4, // 1: controller.api.resources.targets.v1.Target.name:type_name -> google.protobuf.StringValue - 4, // 2: controller.api.resources.targets.v1.Target.description:type_name -> google.protobuf.StringValue - 5, // 3: controller.api.resources.targets.v1.Target.created_time:type_name -> google.protobuf.Timestamp - 5, // 4: controller.api.resources.targets.v1.Target.updated_time:type_name -> google.protobuf.Timestamp - 0, // 5: controller.api.resources.targets.v1.Target.host_sets:type_name -> controller.api.resources.targets.v1.HostSet - 6, // 6: controller.api.resources.targets.v1.Target.attributes:type_name -> google.protobuf.Struct - 7, // 7: controller.api.resources.targets.v1.TcpTargetAttributes.default_port:type_name -> google.protobuf.UInt32Value - 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 + 6, // 0: controller.api.resources.targets.v1.Target.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo + 7, // 1: controller.api.resources.targets.v1.Target.name:type_name -> google.protobuf.StringValue + 7, // 2: controller.api.resources.targets.v1.Target.description:type_name -> google.protobuf.StringValue + 8, // 3: controller.api.resources.targets.v1.Target.created_time:type_name -> google.protobuf.Timestamp + 8, // 4: controller.api.resources.targets.v1.Target.updated_time:type_name -> google.protobuf.Timestamp + 0, // 5: controller.api.resources.targets.v1.Target.host_sets:type_name -> controller.api.resources.targets.v1.HostSet + 9, // 6: controller.api.resources.targets.v1.Target.attributes:type_name -> google.protobuf.Struct + 10, // 7: controller.api.resources.targets.v1.TcpTargetAttributes.default_port:type_name -> google.protobuf.UInt32Value + 6, // 8: controller.api.resources.targets.v1.SessionAuthorizationData.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo + 8, // 9: controller.api.resources.targets.v1.SessionAuthorizationData.created_time:type_name -> google.protobuf.Timestamp + 3, // 10: controller.api.resources.targets.v1.SessionAuthorizationData.worker_info:type_name -> controller.api.resources.targets.v1.WorkerInfo + 6, // 11: controller.api.resources.targets.v1.SessionAuthorization.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo + 8, // 12: controller.api.resources.targets.v1.SessionAuthorization.created_time:type_name -> google.protobuf.Timestamp + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_controller_api_resources_targets_v1_target_proto_init() } @@ -448,6 +779,42 @@ func file_controller_api_resources_targets_v1_target_proto_init() { return nil } } + file_controller_api_resources_targets_v1_target_proto_msgTypes[3].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_targets_v1_target_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionAuthorizationData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_resources_targets_v1_target_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionAuthorization); 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{ @@ -455,7 +822,7 @@ func file_controller_api_resources_targets_v1_target_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_api_resources_targets_v1_target_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/gen/controller/api/services/target_service.pb.go b/internal/gen/controller/api/services/target_service.pb.go index 7e67adf28..bdc0995dd 100644 --- a/internal/gen/controller/api/services/target_service.pb.go +++ b/internal/gen/controller/api/services/target_service.pb.go @@ -765,7 +765,6 @@ type RemoveTargetHostSetsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // This host set's id. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` // A list of host set IDs which should not be in the target when this request @@ -873,6 +872,110 @@ func (x *RemoveTargetHostSetsResponse) GetItem() *targets.Target { return nil } +type AuthorizeSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // An optional parameter allowing specification of the particular host within + // the target's host sets to connect to during this session. + HostId string `protobuf:"bytes,2,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty"` +} + +func (x *AuthorizeSessionRequest) Reset() { + *x = AuthorizeSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_target_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthorizeSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorizeSessionRequest) ProtoMessage() {} + +func (x *AuthorizeSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_target_service_proto_msgTypes[16] + 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 AuthorizeSessionRequest.ProtoReflect.Descriptor instead. +func (*AuthorizeSessionRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_target_service_proto_rawDescGZIP(), []int{16} +} + +func (x *AuthorizeSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *AuthorizeSessionRequest) GetHostId() string { + if x != nil { + return x.HostId + } + return "" +} + +type AuthorizeSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *targets.SessionAuthorization `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *AuthorizeSessionResponse) Reset() { + *x = AuthorizeSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_target_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthorizeSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorizeSessionResponse) ProtoMessage() {} + +func (x *AuthorizeSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_target_service_proto_msgTypes[17] + 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 AuthorizeSessionResponse.ProtoReflect.Descriptor instead. +func (*AuthorizeSessionResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_target_service_proto_rawDescGZIP(), []int{17} +} + +func (x *AuthorizeSessionResponse) GetItem() *targets.SessionAuthorization { + if x != nil { + return x.Item + } + return nil +} + var File_controller_api_services_v1_target_service_proto protoreflect.FileDescriptor var file_controller_api_services_v1_target_service_proto_rawDesc = []byte{ @@ -979,107 +1082,131 @@ var file_controller_api_services_v1_target_service_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x2b, 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, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xf0, 0x0b, 0x0a, 0x0d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa1, 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2c, 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, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 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, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, - 0x65, 0x6d, 0x92, 0x41, 0x16, 0x12, 0x14, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, - 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x99, 0x01, 0x0a, 0x0b, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 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, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 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, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x73, 0x92, 0x41, 0x13, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0xae, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x42, 0x0a, 0x17, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 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, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x22, 0x69, 0x0a, 0x18, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x39, 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, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, + 0x69, 0x74, 0x65, 0x6d, 0x32, 0xb6, 0x0d, 0x0a, 0x0d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa1, 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x2c, 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, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 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, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, + 0x6d, 0x92, 0x41, 0x16, 0x12, 0x14, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x99, 0x01, 0x0a, 0x0b, 0x4c, + 0x69, 0x73, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 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, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 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, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, + 0x92, 0x41, 0x13, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0xae, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 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, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 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, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 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, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x19, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, - 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x19, 0x12, - 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, - 0x65, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 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, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 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, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1e, 0x32, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, - 0x65, 0x6d, 0x92, 0x41, 0x12, 0x12, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, - 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0xa0, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x19, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x3a, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x19, 0x12, 0x17, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, + 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0xac, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 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, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 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, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, - 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92, 0x41, 0x12, 0x12, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x73, 0x20, 0x61, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0xda, 0x01, 0x0a, 0x11, 0x41, - 0x64, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, - 0x12, 0x34, 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, 0x41, 0x64, - 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 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, 0x41, 0x64, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, - 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x58, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x68, 0x6f, 0x73, 0x74, - 0x2d, 0x73, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, - 0x26, 0x12, 0x24, 0x41, 0x64, 0x64, 0x73, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, - 0x20, 0x48, 0x6f, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x12, 0xd7, 0x01, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x12, 0x34, 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, 0x53, 0x65, 0x74, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1e, 0x32, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, + 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, + 0x6d, 0x92, 0x41, 0x12, 0x12, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0xa0, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 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, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 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, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x92, 0x41, 0x12, 0x12, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, + 0x20, 0x61, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0xc3, 0x01, 0x0a, 0x10, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, + 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, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x34, 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, 0x53, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x68, 0x6f, 0x73, 0x74, 0x2d, 0x73, 0x65, - 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x23, 0x12, 0x21, - 0x53, 0x65, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, 0x6f, 0x73, 0x74, 0x20, 0x53, 0x65, - 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x2e, 0x12, 0xe4, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x12, 0x37, 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, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x38, 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, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, - 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x68, - 0x6f, 0x73, 0x74, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, - 0x6d, 0x92, 0x41, 0x24, 0x12, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x48, 0x6f, - 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 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, + 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x25, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x3a, 0x01, 0x2a, + 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x16, 0x12, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x73, 0x20, 0x61, 0x20, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0xda, 0x01, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, + 0x74, 0x53, 0x65, 0x74, 0x73, 0x12, 0x34, 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, 0x41, 0x64, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, + 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 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, 0x41, 0x64, 0x64, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x58, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, + 0x2d, 0x68, 0x6f, 0x73, 0x74, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, + 0x74, 0x65, 0x6d, 0x92, 0x41, 0x26, 0x12, 0x24, 0x41, 0x64, 0x64, 0x73, 0x20, 0x65, 0x78, 0x69, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x48, 0x6f, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x12, 0xd7, 0x01, 0x0a, + 0x11, 0x53, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, + 0x74, 0x73, 0x12, 0x34, 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, + 0x53, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 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, 0x53, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, + 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x55, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x68, 0x6f, + 0x73, 0x74, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, + 0x92, 0x41, 0x23, 0x12, 0x21, 0x53, 0x65, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, 0x6f, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x12, 0xe4, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x12, + 0x37, 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, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 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, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x59, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x2d, 0x68, 0x6f, 0x73, 0x74, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, + 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x24, 0x12, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x73, 0x20, 0x48, 0x6f, 0x73, 0x74, 0x20, 0x53, 0x65, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 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 ( @@ -1094,7 +1221,7 @@ func file_controller_api_services_v1_target_service_proto_rawDescGZIP() []byte { return file_controller_api_services_v1_target_service_proto_rawDescData } -var file_controller_api_services_v1_target_service_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_controller_api_services_v1_target_service_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_controller_api_services_v1_target_service_proto_goTypes = []interface{}{ (*GetTargetRequest)(nil), // 0: controller.api.services.v1.GetTargetRequest (*GetTargetResponse)(nil), // 1: controller.api.services.v1.GetTargetResponse @@ -1112,41 +1239,47 @@ var file_controller_api_services_v1_target_service_proto_goTypes = []interface{} (*SetTargetHostSetsResponse)(nil), // 13: controller.api.services.v1.SetTargetHostSetsResponse (*RemoveTargetHostSetsRequest)(nil), // 14: controller.api.services.v1.RemoveTargetHostSetsRequest (*RemoveTargetHostSetsResponse)(nil), // 15: controller.api.services.v1.RemoveTargetHostSetsResponse - (*targets.Target)(nil), // 16: controller.api.resources.targets.v1.Target - (*field_mask.FieldMask)(nil), // 17: google.protobuf.FieldMask + (*AuthorizeSessionRequest)(nil), // 16: controller.api.services.v1.AuthorizeSessionRequest + (*AuthorizeSessionResponse)(nil), // 17: controller.api.services.v1.AuthorizeSessionResponse + (*targets.Target)(nil), // 18: controller.api.resources.targets.v1.Target + (*field_mask.FieldMask)(nil), // 19: google.protobuf.FieldMask + (*targets.SessionAuthorization)(nil), // 20: controller.api.resources.targets.v1.SessionAuthorization } var file_controller_api_services_v1_target_service_proto_depIdxs = []int32{ - 16, // 0: controller.api.services.v1.GetTargetResponse.item:type_name -> controller.api.resources.targets.v1.Target - 16, // 1: controller.api.services.v1.ListTargetsResponse.items:type_name -> controller.api.resources.targets.v1.Target - 16, // 2: controller.api.services.v1.CreateTargetRequest.item:type_name -> controller.api.resources.targets.v1.Target - 16, // 3: controller.api.services.v1.CreateTargetResponse.item:type_name -> controller.api.resources.targets.v1.Target - 16, // 4: controller.api.services.v1.UpdateTargetRequest.item:type_name -> controller.api.resources.targets.v1.Target - 17, // 5: controller.api.services.v1.UpdateTargetRequest.update_mask:type_name -> google.protobuf.FieldMask - 16, // 6: controller.api.services.v1.UpdateTargetResponse.item:type_name -> controller.api.resources.targets.v1.Target - 16, // 7: controller.api.services.v1.AddTargetHostSetsResponse.item:type_name -> controller.api.resources.targets.v1.Target - 16, // 8: controller.api.services.v1.SetTargetHostSetsResponse.item:type_name -> controller.api.resources.targets.v1.Target - 16, // 9: controller.api.services.v1.RemoveTargetHostSetsResponse.item:type_name -> controller.api.resources.targets.v1.Target - 0, // 10: controller.api.services.v1.TargetService.GetTarget:input_type -> controller.api.services.v1.GetTargetRequest - 2, // 11: controller.api.services.v1.TargetService.ListTargets:input_type -> controller.api.services.v1.ListTargetsRequest - 4, // 12: controller.api.services.v1.TargetService.CreateTarget:input_type -> controller.api.services.v1.CreateTargetRequest - 6, // 13: controller.api.services.v1.TargetService.UpdateTarget:input_type -> controller.api.services.v1.UpdateTargetRequest - 8, // 14: controller.api.services.v1.TargetService.DeleteTarget:input_type -> controller.api.services.v1.DeleteTargetRequest - 10, // 15: controller.api.services.v1.TargetService.AddTargetHostSets:input_type -> controller.api.services.v1.AddTargetHostSetsRequest - 12, // 16: controller.api.services.v1.TargetService.SetTargetHostSets:input_type -> controller.api.services.v1.SetTargetHostSetsRequest - 14, // 17: controller.api.services.v1.TargetService.RemoveTargetHostSets:input_type -> controller.api.services.v1.RemoveTargetHostSetsRequest - 1, // 18: controller.api.services.v1.TargetService.GetTarget:output_type -> controller.api.services.v1.GetTargetResponse - 3, // 19: controller.api.services.v1.TargetService.ListTargets:output_type -> controller.api.services.v1.ListTargetsResponse - 5, // 20: controller.api.services.v1.TargetService.CreateTarget:output_type -> controller.api.services.v1.CreateTargetResponse - 7, // 21: controller.api.services.v1.TargetService.UpdateTarget:output_type -> controller.api.services.v1.UpdateTargetResponse - 9, // 22: controller.api.services.v1.TargetService.DeleteTarget:output_type -> controller.api.services.v1.DeleteTargetResponse - 11, // 23: controller.api.services.v1.TargetService.AddTargetHostSets:output_type -> controller.api.services.v1.AddTargetHostSetsResponse - 13, // 24: controller.api.services.v1.TargetService.SetTargetHostSets:output_type -> controller.api.services.v1.SetTargetHostSetsResponse - 15, // 25: controller.api.services.v1.TargetService.RemoveTargetHostSets:output_type -> controller.api.services.v1.RemoveTargetHostSetsResponse - 18, // [18:26] is the sub-list for method output_type - 10, // [10:18] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 18, // 0: controller.api.services.v1.GetTargetResponse.item:type_name -> controller.api.resources.targets.v1.Target + 18, // 1: controller.api.services.v1.ListTargetsResponse.items:type_name -> controller.api.resources.targets.v1.Target + 18, // 2: controller.api.services.v1.CreateTargetRequest.item:type_name -> controller.api.resources.targets.v1.Target + 18, // 3: controller.api.services.v1.CreateTargetResponse.item:type_name -> controller.api.resources.targets.v1.Target + 18, // 4: controller.api.services.v1.UpdateTargetRequest.item:type_name -> controller.api.resources.targets.v1.Target + 19, // 5: controller.api.services.v1.UpdateTargetRequest.update_mask:type_name -> google.protobuf.FieldMask + 18, // 6: controller.api.services.v1.UpdateTargetResponse.item:type_name -> controller.api.resources.targets.v1.Target + 18, // 7: controller.api.services.v1.AddTargetHostSetsResponse.item:type_name -> controller.api.resources.targets.v1.Target + 18, // 8: controller.api.services.v1.SetTargetHostSetsResponse.item:type_name -> controller.api.resources.targets.v1.Target + 18, // 9: controller.api.services.v1.RemoveTargetHostSetsResponse.item:type_name -> controller.api.resources.targets.v1.Target + 20, // 10: controller.api.services.v1.AuthorizeSessionResponse.item:type_name -> controller.api.resources.targets.v1.SessionAuthorization + 0, // 11: controller.api.services.v1.TargetService.GetTarget:input_type -> controller.api.services.v1.GetTargetRequest + 2, // 12: controller.api.services.v1.TargetService.ListTargets:input_type -> controller.api.services.v1.ListTargetsRequest + 4, // 13: controller.api.services.v1.TargetService.CreateTarget:input_type -> controller.api.services.v1.CreateTargetRequest + 6, // 14: controller.api.services.v1.TargetService.UpdateTarget:input_type -> controller.api.services.v1.UpdateTargetRequest + 8, // 15: controller.api.services.v1.TargetService.DeleteTarget:input_type -> controller.api.services.v1.DeleteTargetRequest + 16, // 16: controller.api.services.v1.TargetService.AuthorizeSession:input_type -> controller.api.services.v1.AuthorizeSessionRequest + 10, // 17: controller.api.services.v1.TargetService.AddTargetHostSets:input_type -> controller.api.services.v1.AddTargetHostSetsRequest + 12, // 18: controller.api.services.v1.TargetService.SetTargetHostSets:input_type -> controller.api.services.v1.SetTargetHostSetsRequest + 14, // 19: controller.api.services.v1.TargetService.RemoveTargetHostSets:input_type -> controller.api.services.v1.RemoveTargetHostSetsRequest + 1, // 20: controller.api.services.v1.TargetService.GetTarget:output_type -> controller.api.services.v1.GetTargetResponse + 3, // 21: controller.api.services.v1.TargetService.ListTargets:output_type -> controller.api.services.v1.ListTargetsResponse + 5, // 22: controller.api.services.v1.TargetService.CreateTarget:output_type -> controller.api.services.v1.CreateTargetResponse + 7, // 23: controller.api.services.v1.TargetService.UpdateTarget:output_type -> controller.api.services.v1.UpdateTargetResponse + 9, // 24: controller.api.services.v1.TargetService.DeleteTarget:output_type -> controller.api.services.v1.DeleteTargetResponse + 17, // 25: controller.api.services.v1.TargetService.AuthorizeSession:output_type -> controller.api.services.v1.AuthorizeSessionResponse + 11, // 26: controller.api.services.v1.TargetService.AddTargetHostSets:output_type -> controller.api.services.v1.AddTargetHostSetsResponse + 13, // 27: controller.api.services.v1.TargetService.SetTargetHostSets:output_type -> controller.api.services.v1.SetTargetHostSetsResponse + 15, // 28: controller.api.services.v1.TargetService.RemoveTargetHostSets:output_type -> controller.api.services.v1.RemoveTargetHostSetsResponse + 20, // [20:29] is the sub-list for method output_type + 11, // [11:20] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_controller_api_services_v1_target_service_proto_init() } @@ -1347,6 +1480,30 @@ func file_controller_api_services_v1_target_service_proto_init() { return nil } } + file_controller_api_services_v1_target_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthorizeSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_target_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthorizeSessionResponse); 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{ @@ -1354,7 +1511,7 @@ func file_controller_api_services_v1_target_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_api_services_v1_target_service_proto_rawDesc, NumEnums: 0, - NumMessages: 16, + NumMessages: 18, NumExtensions: 0, NumServices: 1, }, @@ -1411,6 +1568,8 @@ type TargetServiceClient interface { // specifies if the resource existed before the DeleteTarget request was // received. DeleteTarget(ctx context.Context, in *DeleteTargetRequest, opts ...grpc.CallOption) (*DeleteTargetResponse, error) + // AuthorizeSession creates authorization information from a given target. + AuthorizeSession(ctx context.Context, in *AuthorizeSessionRequest, opts ...grpc.CallOption) (*AuthorizeSessionResponse, error) // AddTargetHostSets adds host sets to this target. The provided request must // include the scope ID and the target ID to which the host sets will be added. // All host sets added to the provided target must be a child of a catalog that @@ -1487,6 +1646,15 @@ func (c *targetServiceClient) DeleteTarget(ctx context.Context, in *DeleteTarget return out, nil } +func (c *targetServiceClient) AuthorizeSession(ctx context.Context, in *AuthorizeSessionRequest, opts ...grpc.CallOption) (*AuthorizeSessionResponse, error) { + out := new(AuthorizeSessionResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.TargetService/AuthorizeSession", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *targetServiceClient) AddTargetHostSets(ctx context.Context, in *AddTargetHostSetsRequest, opts ...grpc.CallOption) (*AddTargetHostSetsResponse, error) { out := new(AddTargetHostSetsResponse) err := c.cc.Invoke(ctx, "/controller.api.services.v1.TargetService/AddTargetHostSets", in, out, opts...) @@ -1547,6 +1715,8 @@ type TargetServiceServer interface { // specifies if the resource existed before the DeleteTarget request was // received. DeleteTarget(context.Context, *DeleteTargetRequest) (*DeleteTargetResponse, error) + // AuthorizeSession creates authorization information from a given target. + AuthorizeSession(context.Context, *AuthorizeSessionRequest) (*AuthorizeSessionResponse, error) // AddTargetHostSets adds host sets to this target. The provided request must // include the scope ID and the target ID to which the host sets will be added. // All host sets added to the provided target must be a child of a catalog that @@ -1589,6 +1759,9 @@ func (*UnimplementedTargetServiceServer) UpdateTarget(context.Context, *UpdateTa func (*UnimplementedTargetServiceServer) DeleteTarget(context.Context, *DeleteTargetRequest) (*DeleteTargetResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteTarget not implemented") } +func (*UnimplementedTargetServiceServer) AuthorizeSession(context.Context, *AuthorizeSessionRequest) (*AuthorizeSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AuthorizeSession not implemented") +} func (*UnimplementedTargetServiceServer) AddTargetHostSets(context.Context, *AddTargetHostSetsRequest) (*AddTargetHostSetsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddTargetHostSets not implemented") } @@ -1693,6 +1866,24 @@ func _TargetService_DeleteTarget_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _TargetService_AuthorizeSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthorizeSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TargetServiceServer).AuthorizeSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.TargetService/AuthorizeSession", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TargetServiceServer).AuthorizeSession(ctx, req.(*AuthorizeSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TargetService_AddTargetHostSets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddTargetHostSetsRequest) if err := dec(in); err != nil { @@ -1771,6 +1962,10 @@ var _TargetService_serviceDesc = grpc.ServiceDesc{ MethodName: "DeleteTarget", Handler: _TargetService_DeleteTarget_Handler, }, + { + MethodName: "AuthorizeSession", + Handler: _TargetService_AuthorizeSession_Handler, + }, { MethodName: "AddTargetHostSets", Handler: _TargetService_AddTargetHostSets_Handler, diff --git a/internal/gen/controller/api/services/target_service.pb.gw.go b/internal/gen/controller/api/services/target_service.pb.gw.go index 5a877532f..7c231a651 100644 --- a/internal/gen/controller/api/services/target_service.pb.gw.go +++ b/internal/gen/controller/api/services/target_service.pb.gw.go @@ -321,6 +321,74 @@ func local_request_TargetService_DeleteTarget_0(ctx context.Context, marshaler r } +func request_TargetService_AuthorizeSession_0(ctx context.Context, marshaler runtime.Marshaler, client TargetServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthorizeSessionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + 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) + } + + msg, err := client.AuthorizeSession(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TargetService_AuthorizeSession_0(ctx context.Context, marshaler runtime.Marshaler, server TargetServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthorizeSessionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + 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) + } + + msg, err := server.AuthorizeSession(ctx, &protoReq) + return msg, metadata, err + +} + func request_TargetService_AddTargetHostSets_0(ctx context.Context, marshaler runtime.Marshaler, client TargetServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq AddTargetHostSetsRequest var metadata runtime.ServerMetadata @@ -631,6 +699,26 @@ func RegisterTargetServiceHandlerServer(ctx context.Context, mux *runtime.ServeM }) + mux.Handle("POST", pattern_TargetService_AuthorizeSession_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.TargetService/AuthorizeSession") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TargetService_AuthorizeSession_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_TargetService_AuthorizeSession_0(ctx, mux, outboundMarshaler, w, req, response_TargetService_AuthorizeSession_0{resp}, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_TargetService_AddTargetHostSets_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -832,6 +920,26 @@ func RegisterTargetServiceHandlerClient(ctx context.Context, mux *runtime.ServeM }) + mux.Handle("POST", pattern_TargetService_AuthorizeSession_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.TargetService/AuthorizeSession") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TargetService_AuthorizeSession_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_TargetService_AuthorizeSession_0(ctx, mux, outboundMarshaler, w, req, response_TargetService_AuthorizeSession_0{resp}, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_TargetService_AddTargetHostSets_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -922,6 +1030,15 @@ func (m response_TargetService_UpdateTarget_0) XXX_ResponseBody() interface{} { return response.Item } +type response_TargetService_AuthorizeSession_0 struct { + proto.Message +} + +func (m response_TargetService_AuthorizeSession_0) XXX_ResponseBody() interface{} { + response := m.Message.(*AuthorizeSessionResponse) + return response.Item +} + type response_TargetService_AddTargetHostSets_0 struct { proto.Message } @@ -960,6 +1077,8 @@ var ( pattern_TargetService_DeleteTarget_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "targets", "id"}, "")) + pattern_TargetService_AuthorizeSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "targets", "id"}, "authorize")) + pattern_TargetService_AddTargetHostSets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "targets", "id"}, "add-host-sets")) pattern_TargetService_SetTargetHostSets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "targets", "id"}, "set-host-sets")) @@ -978,6 +1097,8 @@ var ( forward_TargetService_DeleteTarget_0 = runtime.ForwardResponseMessage + forward_TargetService_AuthorizeSession_0 = runtime.ForwardResponseMessage + forward_TargetService_AddTargetHostSets_0 = runtime.ForwardResponseMessage forward_TargetService_SetTargetHostSets_0 = runtime.ForwardResponseMessage diff --git a/internal/gen/controller/servers/services/session_service.pb.go b/internal/gen/controller/servers/services/session_service.pb.go index fe610b140..a49574a22 100644 --- a/internal/gen/controller/servers/services/session_service.pb.go +++ b/internal/gen/controller/servers/services/session_service.pb.go @@ -10,7 +10,7 @@ import ( context "context" proto "github.com/golang/protobuf/proto" _ "github.com/golang/protobuf/ptypes/timestamp" - sessions "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + targets "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" _ "github.com/hashicorp/boundary/internal/servers" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -32,17 +32,17 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 -type GetSessionRequest struct { +type LookupSessionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The session ID from the client - Id string `protobuf:"bytes,10,opt,name=id,proto3" json:"id,omitempty"` + SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` } -func (x *GetSessionRequest) Reset() { - *x = GetSessionRequest{} +func (x *LookupSessionRequest) Reset() { + *x = LookupSessionRequest{} if protoimpl.UnsafeEnabled { mi := &file_controller_servers_services_v1_session_service_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -50,13 +50,13 @@ func (x *GetSessionRequest) Reset() { } } -func (x *GetSessionRequest) String() string { +func (x *LookupSessionRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetSessionRequest) ProtoMessage() {} +func (*LookupSessionRequest) ProtoMessage() {} -func (x *GetSessionRequest) ProtoReflect() protoreflect.Message { +func (x *LookupSessionRequest) ProtoReflect() protoreflect.Message { mi := &file_controller_servers_services_v1_session_service_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -68,29 +68,33 @@ func (x *GetSessionRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetSessionRequest.ProtoReflect.Descriptor instead. -func (*GetSessionRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupSessionRequest.ProtoReflect.Descriptor instead. +func (*LookupSessionRequest) Descriptor() ([]byte, []int) { return file_controller_servers_services_v1_session_service_proto_rawDescGZIP(), []int{0} } -func (x *GetSessionRequest) GetId() string { +func (x *LookupSessionRequest) GetSessionId() string { if x != nil { - return x.Id + return x.SessionId } return "" } -// SessionResponse contains information necessary for a client to establish a session -type GetSessionResponse struct { +// LookupSessionResponse contains information necessary for a client to +// establish a session. +type LookupSessionResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Session *sessions.Session `protobuf:"bytes,1,opt,name=session,proto3" json:"session,omitempty"` + Authorization *targets.SessionAuthorizationData `protobuf:"bytes,10,opt,name=authorization,proto3" json:"authorization,omitempty"` + TofuToken string `protobuf:"bytes,20,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty"` + Version uint32 `protobuf:"varint,30,opt,name=version,proto3" json:"version,omitempty"` + Endpoint string `protobuf:"bytes,40,opt,name=endpoint,proto3" json:"endpoint,omitempty"` } -func (x *GetSessionResponse) Reset() { - *x = GetSessionResponse{} +func (x *LookupSessionResponse) Reset() { + *x = LookupSessionResponse{} if protoimpl.UnsafeEnabled { mi := &file_controller_servers_services_v1_session_service_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -98,13 +102,13 @@ func (x *GetSessionResponse) Reset() { } } -func (x *GetSessionResponse) String() string { +func (x *LookupSessionResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetSessionResponse) ProtoMessage() {} +func (*LookupSessionResponse) ProtoMessage() {} -func (x *GetSessionResponse) ProtoReflect() protoreflect.Message { +func (x *LookupSessionResponse) ProtoReflect() protoreflect.Message { mi := &file_controller_servers_services_v1_session_service_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -116,18 +120,148 @@ func (x *GetSessionResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetSessionResponse.ProtoReflect.Descriptor instead. -func (*GetSessionResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupSessionResponse.ProtoReflect.Descriptor instead. +func (*LookupSessionResponse) Descriptor() ([]byte, []int) { return file_controller_servers_services_v1_session_service_proto_rawDescGZIP(), []int{1} } -func (x *GetSessionResponse) GetSession() *sessions.Session { +func (x *LookupSessionResponse) GetAuthorization() *targets.SessionAuthorizationData { if x != nil { - return x.Session + return x.Authorization } return nil } +func (x *LookupSessionResponse) GetTofuToken() string { + if x != nil { + return x.TofuToken + } + return "" +} + +func (x *LookupSessionResponse) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *LookupSessionResponse) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +type ActivateSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SessionId string `protobuf:"bytes,10,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + TofuToken string `protobuf:"bytes,20,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty"` + Version uint32 `protobuf:"varint,30,opt,name=version,proto3" json:"version,omitempty"` + WorkerId string `protobuf:"bytes,40,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"` +} + +func (x *ActivateSessionRequest) Reset() { + *x = ActivateSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_servers_services_v1_session_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActivateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActivateSessionRequest) ProtoMessage() {} + +func (x *ActivateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_servers_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 ActivateSessionRequest.ProtoReflect.Descriptor instead. +func (*ActivateSessionRequest) Descriptor() ([]byte, []int) { + return file_controller_servers_services_v1_session_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ActivateSessionRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ActivateSessionRequest) GetTofuToken() string { + if x != nil { + return x.TofuToken + } + return "" +} + +func (x *ActivateSessionRequest) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *ActivateSessionRequest) GetWorkerId() string { + if x != nil { + return x.WorkerId + } + return "" +} + +type ActivateSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ActivateSessionResponse) Reset() { + *x = ActivateSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_servers_services_v1_session_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActivateSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActivateSessionResponse) ProtoMessage() {} + +func (x *ActivateSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_servers_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 ActivateSessionResponse.ProtoReflect.Descriptor instead. +func (*ActivateSessionResponse) Descriptor() ([]byte, []int) { + return file_controller_servers_services_v1_session_service_proto_rawDescGZIP(), []int{3} +} + var File_controller_servers_services_v1_session_service_proto protoreflect.FileDescriptor var file_controller_servers_services_v1_session_service_proto_rawDesc = []byte{ @@ -140,26 +274,54 @@ var file_controller_servers_services_v1_session_service_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x63, 0x6f, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 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, 0x23, 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, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 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, 0x07, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x87, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 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, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x76, + 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, + 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xd1, 0x01, 0x0a, 0x15, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x63, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 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, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1e, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x16, 0x41, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1e, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, + 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x64, 0x22, 0x19, 0x0a, 0x17, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x97, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7e, 0x0a, 0x0d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x84, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x51, 0x5a, 0x4f, 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, @@ -181,18 +343,22 @@ func file_controller_servers_services_v1_session_service_proto_rawDescGZIP() []b return file_controller_servers_services_v1_session_service_proto_rawDescData } -var file_controller_servers_services_v1_session_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_controller_servers_services_v1_session_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_controller_servers_services_v1_session_service_proto_goTypes = []interface{}{ - (*GetSessionRequest)(nil), // 0: controller.servers.services.v1.GetSessionRequest - (*GetSessionResponse)(nil), // 1: controller.servers.services.v1.GetSessionResponse - (*sessions.Session)(nil), // 2: controller.api.resources.sessions.v1.Session + (*LookupSessionRequest)(nil), // 0: controller.servers.services.v1.LookupSessionRequest + (*LookupSessionResponse)(nil), // 1: controller.servers.services.v1.LookupSessionResponse + (*ActivateSessionRequest)(nil), // 2: controller.servers.services.v1.ActivateSessionRequest + (*ActivateSessionResponse)(nil), // 3: controller.servers.services.v1.ActivateSessionResponse + (*targets.SessionAuthorizationData)(nil), // 4: controller.api.resources.targets.v1.SessionAuthorizationData } var file_controller_servers_services_v1_session_service_proto_depIdxs = []int32{ - 2, // 0: controller.servers.services.v1.GetSessionResponse.session:type_name -> controller.api.resources.sessions.v1.Session - 0, // 1: controller.servers.services.v1.SessionService.GetSession:input_type -> controller.servers.services.v1.GetSessionRequest - 1, // 2: controller.servers.services.v1.SessionService.GetSession:output_type -> controller.servers.services.v1.GetSessionResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type + 4, // 0: controller.servers.services.v1.LookupSessionResponse.authorization:type_name -> controller.api.resources.targets.v1.SessionAuthorizationData + 0, // 1: controller.servers.services.v1.SessionService.LookupSession:input_type -> controller.servers.services.v1.LookupSessionRequest + 2, // 2: controller.servers.services.v1.SessionService.ActivateSession:input_type -> controller.servers.services.v1.ActivateSessionRequest + 1, // 3: controller.servers.services.v1.SessionService.LookupSession:output_type -> controller.servers.services.v1.LookupSessionResponse + 3, // 4: controller.servers.services.v1.SessionService.ActivateSession:output_type -> controller.servers.services.v1.ActivateSessionResponse + 3, // [3:5] is the sub-list for method output_type + 1, // [1:3] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name 1, // [1:1] is the sub-list for extension extendee 0, // [0:1] is the sub-list for field type_name @@ -205,7 +371,7 @@ func file_controller_servers_services_v1_session_service_proto_init() { } if !protoimpl.UnsafeEnabled { file_controller_servers_services_v1_session_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSessionRequest); i { + switch v := v.(*LookupSessionRequest); i { case 0: return &v.state case 1: @@ -217,7 +383,31 @@ func file_controller_servers_services_v1_session_service_proto_init() { } } file_controller_servers_services_v1_session_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSessionResponse); i { + switch v := v.(*LookupSessionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_servers_services_v1_session_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ActivateSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_servers_services_v1_session_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ActivateSessionResponse); i { case 0: return &v.state case 1: @@ -235,7 +425,7 @@ func file_controller_servers_services_v1_session_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_servers_services_v1_session_service_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, @@ -261,9 +451,11 @@ const _ = grpc.SupportPackageIsVersion6 // // 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 { - // Validate session allows a worker to retrieve session information from the controller. - // This endpoint validates the session - GetSession(ctx context.Context, in *GetSessionRequest, opts ...grpc.CallOption) (*GetSessionResponse, error) + // GetSession allows a worker to retrieve session information from the + // controller. + LookupSession(ctx context.Context, in *LookupSessionRequest, opts ...grpc.CallOption) (*LookupSessionResponse, error) + // ActivateSession allows a worker to activate a session on a controller. + ActivateSession(ctx context.Context, in *ActivateSessionRequest, opts ...grpc.CallOption) (*ActivateSessionResponse, error) } type sessionServiceClient struct { @@ -274,9 +466,18 @@ 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.servers.services.v1.SessionService/GetSession", in, out, opts...) +func (c *sessionServiceClient) LookupSession(ctx context.Context, in *LookupSessionRequest, opts ...grpc.CallOption) (*LookupSessionResponse, error) { + out := new(LookupSessionResponse) + err := c.cc.Invoke(ctx, "/controller.servers.services.v1.SessionService/LookupSession", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionServiceClient) ActivateSession(ctx context.Context, in *ActivateSessionRequest, opts ...grpc.CallOption) (*ActivateSessionResponse, error) { + out := new(ActivateSessionResponse) + err := c.cc.Invoke(ctx, "/controller.servers.services.v1.SessionService/ActivateSession", in, out, opts...) if err != nil { return nil, err } @@ -285,37 +486,60 @@ func (c *sessionServiceClient) GetSession(ctx context.Context, in *GetSessionReq // SessionServiceServer is the server API for SessionService service. type SessionServiceServer interface { - // Validate session allows a worker to retrieve session information from the controller. - // This endpoint validates the session - GetSession(context.Context, *GetSessionRequest) (*GetSessionResponse, error) + // GetSession allows a worker to retrieve session information from the + // controller. + LookupSession(context.Context, *LookupSessionRequest) (*LookupSessionResponse, error) + // ActivateSession allows a worker to activate a session on a controller. + ActivateSession(context.Context, *ActivateSessionRequest) (*ActivateSessionResponse, 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) LookupSession(context.Context, *LookupSessionRequest) (*LookupSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LookupSession not implemented") +} +func (*UnimplementedSessionServiceServer) ActivateSession(context.Context, *ActivateSessionRequest) (*ActivateSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ActivateSession 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) +func _SessionService_LookupSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LookupSessionRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(SessionServiceServer).GetSession(ctx, in) + return srv.(SessionServiceServer).LookupSession(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/controller.servers.services.v1.SessionService/GetSession", + FullMethod: "/controller.servers.services.v1.SessionService/LookupSession", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SessionServiceServer).GetSession(ctx, req.(*GetSessionRequest)) + return srv.(SessionServiceServer).LookupSession(ctx, req.(*LookupSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionService_ActivateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ActivateSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).ActivateSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.servers.services.v1.SessionService/ActivateSession", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).ActivateSession(ctx, req.(*ActivateSessionRequest)) } return interceptor(ctx, in, info, handler) } @@ -325,8 +549,12 @@ var _SessionService_serviceDesc = grpc.ServiceDesc{ HandlerType: (*SessionServiceServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "GetSession", - Handler: _SessionService_GetSession_Handler, + MethodName: "LookupSession", + Handler: _SessionService_LookupSession_Handler, + }, + { + MethodName: "ActivateSession", + Handler: _SessionService_ActivateSession_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/internal/perms/grants_test.go b/internal/perms/grants_test.go index 0c9092280..dc7014ca3 100644 --- a/internal/perms/grants_test.go +++ b/internal/perms/grants_test.go @@ -54,14 +54,14 @@ func Test_ActionParsingValidation(t *testing.T) { { name: "all valid plus all", input: Grant{ - actionsBeingParsed: []string{"list", "create", "update", "*", "read", "delete", "authenticate", "connect"}, + actionsBeingParsed: []string{"list", "create", "update", "*", "read", "delete", "authenticate", "authorize"}, }, errResult: `"*" cannot be specified with other actions`, }, { name: "all valid", input: Grant{ - actionsBeingParsed: []string{"list", "create", "update", "read", "delete", "authenticate", "connect"}, + actionsBeingParsed: []string{"list", "create", "update", "read", "delete", "authenticate", "authorize"}, }, result: Grant{ actions: map[action.Type]bool{ @@ -71,7 +71,7 @@ func Test_ActionParsingValidation(t *testing.T) { action.Read: true, action.Delete: true, action.Authenticate: true, - action.Connect: true, + action.Authorize: true, }, }, }, 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 8d6f22ac6..8ab7208d5 100644 --- a/internal/proto/local/controller/api/resources/sessions/v1/session.proto +++ b/internal/proto/local/controller/api/resources/sessions/v1/session.proto @@ -8,14 +8,9 @@ import "google/protobuf/timestamp.proto"; import "google/protobuf/wrappers.proto"; import "google/protobuf/struct.proto"; 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; -} - // Session contains all fields related to a Session resource message Session { // The ID of the resource @@ -66,5 +61,5 @@ message Session { string endpoint = 140; // Worker information. The first worker in the slice should be prioritized. - repeated WorkerInfo worker_info = 150 [json_name="worker_info"]; + repeated resources.targets.v1.WorkerInfo worker_info = 150 [json_name="worker_info"]; } diff --git a/internal/proto/local/controller/api/resources/targets/v1/target.proto b/internal/proto/local/controller/api/resources/targets/v1/target.proto index 022de406f..040dfa31f 100644 --- a/internal/proto/local/controller/api/resources/targets/v1/target.proto +++ b/internal/proto/local/controller/api/resources/targets/v1/target.proto @@ -62,4 +62,80 @@ message Target { message TcpTargetAttributes { google.protobuf.UInt32Value default_port = 10 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this:"attributes.default_port" that: "DefaultPort"}]; +} + +// WorkerInfo contains information about workers, returned in +// SessionAuthorization +message WorkerInfo { + // The address of the worker + string address = 10; +} + +// SessionAuthorization contains all fields related to authorization for a +// session. It's in the Targets API because it's returned by a target authorize +// action. +message SessionAuthorizationData { + // The ID of the session + // Output only. + string session_id = 10; + + // The id of the target authorizing this session. This must be defined for + // creation of this resource, but is otherwise read only. + // Output only. + string target_id = 20 [json_name="target_id"]; + + // 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"]; + + // Type of the session (e.g. tcp, ssh, etc.) + // Output only. + string type = 80; + + // The certificate to use when connecting (or if using custom certs, to + // serve as the "login"). Raw DER bytes. + // Output only. + bytes certificate = 120; + + // The private key to use when connecting (or if using custom certs, to pass + // as the "password"). We are using Ed25519 so this is purely raw bytes, no + // marshaling. + // Output only. + bytes private_key = 130 [json_name="private_key"]; + + // Worker information. The first worker in the array should be prioritized. + // Output only. + repeated WorkerInfo worker_info = 150 [json_name="worker_info"]; +} + +message SessionAuthorization { + // The ID of the session + // Output only. + string session_id = 10; + + // The id of the target authorizing this session. This must be defined for + // creation of this resource, but is otherwise read only. + // Output only. + string target_id = 20 [json_name="target_id"]; + + // 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"]; + + // Type of the session (e.g. tcp, ssh, etc.) + // Output only. + string type = 80; + + // The marshaled SessionAuthorizationData message containing all information + // that the proxy needs. + // Output only. + string authorization_token = 90; } \ No newline at end of file diff --git a/internal/proto/local/controller/api/services/v1/target_service.proto b/internal/proto/local/controller/api/services/v1/target_service.proto index a456fed15..1bb1e4341 100644 --- a/internal/proto/local/controller/api/services/v1/target_service.proto +++ b/internal/proto/local/controller/api/services/v1/target_service.proto @@ -86,7 +86,18 @@ service TargetService { summary: "Deletes a Target" }; } - + + // AuthorizeSession creates authorization information from a given target. + rpc AuthorizeSession(AuthorizeSessionRequest) returns (AuthorizeSessionResponse) { + option (google.api.http) = { + post: "/v1/targets/{id}:authorize" + body: "*" + response_body: "item" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Authorizes a Session" + }; + } // AddTargetHostSets adds host sets to this target. The provided request must // include the scope ID and the target ID to which the host sets will be added. @@ -213,7 +224,6 @@ message SetTargetHostSetsResponse { } message RemoveTargetHostSetsRequest { - // This host set's id. string id = 1; uint32 version = 2; @@ -225,3 +235,15 @@ message RemoveTargetHostSetsRequest { message RemoveTargetHostSetsResponse { api.resources.targets.v1.Target item = 1; } + +message AuthorizeSessionRequest { + string id = 1; + + // An optional parameter allowing specification of the particular host within + // the target's host sets to connect to during this session. + string host_id = 2; +} + +message AuthorizeSessionResponse { + api.resources.targets.v1.SessionAuthorization item = 1; +} \ No newline at end of file diff --git a/internal/proto/local/controller/servers/services/v1/session_service.proto b/internal/proto/local/controller/servers/services/v1/session_service.proto index e69d9d649..16ac8c0d5 100644 --- a/internal/proto/local/controller/servers/services/v1/session_service.proto +++ b/internal/proto/local/controller/servers/services/v1/session_service.proto @@ -6,20 +6,39 @@ option go_package = "github.com/hashicorp/boundary/internal/gen/controller/serve import "google/protobuf/timestamp.proto"; import "controller/servers/v1/servers.proto"; -import "controller/api/resources/sessions/v1/session.proto"; +import "controller/api/resources/targets/v1/target.proto"; service SessionService { - // Validate session allows a worker to retrieve session information from the controller. - // This endpoint validates the session - rpc GetSession(GetSessionRequest) returns (GetSessionResponse) {} + // GetSession allows a worker to retrieve session information from the + // controller. + rpc LookupSession(LookupSessionRequest) returns (LookupSessionResponse) {} + + // ActivateSession allows a worker to activate a session on a controller. + rpc ActivateSession(ActivateSessionRequest) returns (ActivateSessionResponse) {} } -message GetSessionRequest { +message LookupSessionRequest { // The session ID from the client - string id = 10; + string session_id = 10; } -// SessionResponse contains information necessary for a client to establish a session -message GetSessionResponse { - api.resources.sessions.v1.Session session = 1; -} \ No newline at end of file +// LookupSessionResponse contains information necessary for a client to +// establish a session. +message LookupSessionResponse { + api.resources.targets.v1.SessionAuthorizationData authorization = 10; + + string tofu_token = 20; + + uint32 version = 30; + + string endpoint = 40; +} + +message ActivateSessionRequest { + string session_id = 10; + string tofu_token = 20; + uint32 version = 30; + string worker_id = 40; +} + +message ActivateSessionResponse{} \ No newline at end of file diff --git a/internal/proto/local/worker/proxy/v1/proxy.proto b/internal/proto/local/worker/proxy/v1/proxy.proto index dbc2cfe1f..9a8bd8aa7 100644 --- a/internal/proto/local/worker/proxy/v1/proxy.proto +++ b/internal/proto/local/worker/proxy/v1/proxy.proto @@ -3,6 +3,9 @@ syntax = "proto3"; package worker.proxy.v1; option go_package = "github.com/hashicorp/boundary/internal/proxy;proxy"; -message Handshake { +message ClientHandshake { string tofu_token = 10; } + +message HandshakeResult { +} \ No newline at end of file diff --git a/internal/proxy/proxy.pb.go b/internal/proxy/proxy.pb.go index 992442ee2..9fef0b687 100644 --- a/internal/proxy/proxy.pb.go +++ b/internal/proxy/proxy.pb.go @@ -25,7 +25,7 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 -type Handshake struct { +type ClientHandshake struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -33,8 +33,8 @@ type Handshake struct { TofuToken string `protobuf:"bytes,10,opt,name=tofu_token,json=tofuToken,proto3" json:"tofu_token,omitempty"` } -func (x *Handshake) Reset() { - *x = Handshake{} +func (x *ClientHandshake) Reset() { + *x = ClientHandshake{} if protoimpl.UnsafeEnabled { mi := &file_worker_proxy_v1_proxy_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -42,13 +42,13 @@ func (x *Handshake) Reset() { } } -func (x *Handshake) String() string { +func (x *ClientHandshake) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Handshake) ProtoMessage() {} +func (*ClientHandshake) ProtoMessage() {} -func (x *Handshake) ProtoReflect() protoreflect.Message { +func (x *ClientHandshake) ProtoReflect() protoreflect.Message { mi := &file_worker_proxy_v1_proxy_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -60,31 +60,71 @@ func (x *Handshake) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Handshake.ProtoReflect.Descriptor instead. -func (*Handshake) Descriptor() ([]byte, []int) { +// Deprecated: Use ClientHandshake.ProtoReflect.Descriptor instead. +func (*ClientHandshake) Descriptor() ([]byte, []int) { return file_worker_proxy_v1_proxy_proto_rawDescGZIP(), []int{0} } -func (x *Handshake) GetTofuToken() string { +func (x *ClientHandshake) GetTofuToken() string { if x != nil { return x.TofuToken } return "" } +type HandshakeResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *HandshakeResult) Reset() { + *x = HandshakeResult{} + if protoimpl.UnsafeEnabled { + mi := &file_worker_proxy_v1_proxy_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HandshakeResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HandshakeResult) ProtoMessage() {} + +func (x *HandshakeResult) ProtoReflect() protoreflect.Message { + mi := &file_worker_proxy_v1_proxy_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 HandshakeResult.ProtoReflect.Descriptor instead. +func (*HandshakeResult) Descriptor() ([]byte, []int) { + return file_worker_proxy_v1_proxy_proto_rawDescGZIP(), []int{1} +} + var File_worker_proxy_v1_proxy_proto protoreflect.FileDescriptor var file_worker_proxy_v1_proxy_proto_rawDesc = []byte{ 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x77, - 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x31, 0x22, 0x2a, - 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, - 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x34, 0x5a, 0x32, 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, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x3b, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x31, 0x22, 0x30, + 0x0a, 0x0f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x11, 0x0a, 0x0f, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x42, 0x34, 0x5a, 0x32, 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, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x3b, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -99,9 +139,10 @@ func file_worker_proxy_v1_proxy_proto_rawDescGZIP() []byte { return file_worker_proxy_v1_proxy_proto_rawDescData } -var file_worker_proxy_v1_proxy_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_worker_proxy_v1_proxy_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_worker_proxy_v1_proxy_proto_goTypes = []interface{}{ - (*Handshake)(nil), // 0: worker.proxy.v1.Handshake + (*ClientHandshake)(nil), // 0: worker.proxy.v1.ClientHandshake + (*HandshakeResult)(nil), // 1: worker.proxy.v1.HandshakeResult } var file_worker_proxy_v1_proxy_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -118,7 +159,19 @@ func file_worker_proxy_v1_proxy_proto_init() { } if !protoimpl.UnsafeEnabled { file_worker_proxy_v1_proxy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Handshake); i { + switch v := v.(*ClientHandshake); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_worker_proxy_v1_proxy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HandshakeResult); i { case 0: return &v.state case 1: @@ -136,7 +189,7 @@ func file_worker_proxy_v1_proxy_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_worker_proxy_v1_proxy_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/servers/controller/common/common.go b/internal/servers/controller/common/common.go index b715568cb..8f3e1c03f 100644 --- a/internal/servers/controller/common/common.go +++ b/internal/servers/controller/common/common.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/servers" + "github.com/hashicorp/boundary/internal/session" "github.com/hashicorp/boundary/internal/target" ) @@ -16,4 +17,5 @@ type ( ServersRepoFactory func() (*servers.Repository, error) StaticRepoFactory func() (*static.Repository, error) TargetRepoFactory func() (*target.Repository, error) + SessionRepoFactory func() (*session.Repository, error) ) diff --git a/internal/servers/controller/controller.go b/internal/servers/controller/controller.go index ab0bf2b35..10fa7eb92 100644 --- a/internal/servers/controller/controller.go +++ b/internal/servers/controller/controller.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/servers" "github.com/hashicorp/boundary/internal/servers/controller/common" + "github.com/hashicorp/boundary/internal/session" "github.com/hashicorp/boundary/internal/target" "github.com/hashicorp/go-hclog" "github.com/hashicorp/vault/sdk/helper/base62" @@ -35,7 +36,6 @@ type Controller struct { // Used for testing workerStatusUpdateTimes *sync.Map - jobMap *sync.Map // Repo factory methods AuthTokenRepoFn common.AuthTokenRepoFactory @@ -44,6 +44,7 @@ type Controller struct { ServersRepoFn common.ServersRepoFactory StaticHostRepoFn common.StaticRepoFactory TargetRepoFn common.TargetRepoFactory + SessionRepoFn common.SessionRepoFactory kms *kms.Kms @@ -55,7 +56,6 @@ func New(conf *Config) (*Controller, error) { conf: conf, logger: conf.Logger.Named("controller"), workerStatusUpdateTimes: new(sync.Map), - jobMap: new(sync.Map), } c.started.Store(false) @@ -125,6 +125,9 @@ func New(conf *Config) (*Controller, error) { c.TargetRepoFn = func() (*target.Repository, error) { return target.NewRepository(dbase, dbase, c.kms) } + c.SessionRepoFn = func() (*session.Repository, error) { + return session.NewRepository(dbase, dbase, c.kms) + } c.workerAuthCache = cache.New(0, 0) diff --git a/internal/servers/controller/handler.go b/internal/servers/controller/handler.go index 1463cb58e..331f1bf2a 100644 --- a/internal/servers/controller/handler.go +++ b/internal/servers/controller/handler.go @@ -3,32 +3,23 @@ package controller import ( "context" "encoding/json" - "errors" "fmt" "net/http" "os" "strings" "time" - "github.com/btcsuite/btcutil/base58" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/hashicorp/boundary/api" "github.com/hashicorp/boundary/globals" "github.com/hashicorp/boundary/internal/auth" - pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" "github.com/hashicorp/boundary/internal/gen/controller/api/services" - wpbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" - "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/servers" "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/targets" - "github.com/hashicorp/boundary/internal/session" - "github.com/hashicorp/boundary/internal/types/scope" "github.com/hashicorp/boundary/sdk/strutil" "github.com/hashicorp/shared-secure-libs/configutil" - "github.com/hashicorp/vault/sdk/helper/base62" "github.com/hashicorp/boundary/internal/servers/controller/handlers" "github.com/hashicorp/boundary/internal/servers/controller/handlers/authenticate" @@ -40,8 +31,6 @@ import ( "github.com/hashicorp/boundary/internal/servers/controller/handlers/scopes" "github.com/hashicorp/boundary/internal/servers/controller/handlers/users" "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" ) type HandlerProperties struct { @@ -60,7 +49,6 @@ func (c *Controller) handler(props HandlerProperties) (http.Handler, error) { return nil, err } mux.Handle("/v1/", h) - mux.Handle("/jobtesting", jobTestingHandler(c)) mux.Handle("/", handleUi(c)) corsWrappedHandler := wrapHandlerWithCors(mux, props) @@ -154,7 +142,13 @@ func handleGrpcGateway(c *Controller, props HandlerProperties) (http.Handler, er if err := services.RegisterUserServiceHandlerServer(ctx, mux, us); err != nil { return nil, fmt.Errorf("failed to register user service handler: %w", err) } - ts, err := targets.NewService(c.TargetRepoFn, c.IamRepoFn) + ts, err := targets.NewService( + c.kms, + c.TargetRepoFn, + c.IamRepoFn, + c.ServersRepoFn, + c.SessionRepoFn, + c.StaticHostRepoFn) if err != nil { return nil, fmt.Errorf("failed to create target handler service: %w", err) } @@ -314,95 +308,6 @@ func wrapHandlerWithCors(h http.Handler, props HandlerProperties) http.Handler { }) } -func jobTestingHandler(c *Controller) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - errorResp := func(e error) { - w.Write([]byte(e.Error())) - w.WriteHeader(http.StatusInternalServerError) - } - - if err := r.ParseForm(); err != nil { - errorResp(err) - return - } - endpoint := r.URL.Query().Get("endpoint") - if endpoint == "" { - errorResp(errors.New("missing endpoint query param")) - return - } - - timeout := 15 * time.Second - var err error - if t := r.URL.Query().Get("timeout"); t != "" { - if timeout, err = time.ParseDuration(t); err != nil { - errorResp(fmt.Errorf("error parsing timeout: %w", err)) - return - } - } - - var workers []*pb.WorkerInfo - repo, err := c.ServersRepoFn() - if err != nil { - errorResp(err) - return - } - servers, err := repo.ListServers(r.Context(), servers.ServerTypeWorker) - if err != nil { - errorResp(err) - return - } - for _, v := range servers { - workers = append(workers, &pb.WorkerInfo{Address: v.Address}) - } - - wrapper, err := c.kms.GetWrapper(r.Context(), scope.Global.String(), kms.KeyPurposeSessions) - if err != nil { - errorResp(err) - return - } - jobId, err := base62.Random(10) - if err != nil { - errorResp(err) - return - } - // TODO (jimlambrt 8/2020): this is quite correct. We need to create a - // new session here (in the session repo) which would have a cert. - privKey, certBytes, err := session.TestCert(wrapper, "u_1234567890", jobId) - if err != nil { - errorResp(err) - return - } - - ret := &wpbs.GetSessionResponse{ - Session: &pb.Session{ - Id: jobId, - ScopeId: scope.Global.String(), - UserId: "u_1234567890", - Type: "tcp", - Endpoint: endpoint, - Certificate: certBytes, - PrivateKey: privKey, - WorkerInfo: workers, - ExpirationTime: ×tamppb.Timestamp{Seconds: time.Now().Add(timeout).Unix()}, - }, - } - - marshaled, err := proto.Marshal(ret) - if err != nil { - errorResp(err) - return - } - - if _, err := w.Write([]byte(base58.Encode(marshaled))); err != nil { - errorResp(err) - return - } - - ret.Session.PrivateKey = nil - c.jobMap.Store(jobId, ret.GetSession()) - }) -} - /* func WrapForwardedForHandler(h http.Handler, authorizedAddrs []*sockaddr.SockAddrMarshaler, rejectNotPresent, rejectNonAuthz bool, hopSkips int) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/internal/servers/controller/handlers/hosts/host_service.go b/internal/servers/controller/handlers/hosts/host_service.go index 2d97f7ae2..b1efc3219 100644 --- a/internal/servers/controller/handlers/hosts/host_service.go +++ b/internal/servers/controller/handlers/hosts/host_service.go @@ -3,6 +3,7 @@ package hosts import ( "context" "fmt" + "net" "strings" "github.com/hashicorp/boundary/internal/auth" @@ -357,6 +358,15 @@ func validateCreateRequest(req *pbs.CreateHostRequest) error { len(attrs.GetAddress().GetValue()) > static.MaxHostAddressLength { badFields["attributes.address"] = fmt.Sprintf("Address length must be between %d and %d characters.", static.MinHostAddressLength, static.MaxHostAddressLength) } + _, _, err := net.SplitHostPort(attrs.GetAddress().GetValue()) + switch { + case err == nil: + badFields["attributes.address"] = "Address for static hosts does not support a port." + case strings.Contains(err.Error(), "missing port in address"): + // Bare hostname, which we want + default: + badFields["attributes.address"] = fmt.Sprintf("Error parsing address: %v.", err) + } } return badFields }) diff --git a/internal/servers/controller/handlers/targets/target_service.go b/internal/servers/controller/handlers/targets/target_service.go index 9bee5e0ee..81ad17db6 100644 --- a/internal/servers/controller/handlers/targets/target_service.go +++ b/internal/servers/controller/handlers/targets/target_service.go @@ -4,14 +4,21 @@ import ( "context" "errors" "fmt" + "math/rand" + "net/url" + "github.com/btcsuite/btcutil/base58" "github.com/golang/protobuf/ptypes/wrappers" "github.com/hashicorp/boundary/internal/auth" "github.com/hashicorp/boundary/internal/db" pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" + "github.com/hashicorp/boundary/internal/host" + "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/servers" "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/target" "github.com/hashicorp/boundary/internal/target/store" "github.com/hashicorp/boundary/internal/types/action" @@ -19,6 +26,7 @@ import ( "github.com/hashicorp/boundary/internal/types/scope" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -35,19 +43,45 @@ func init() { // Service handles request as described by the pbs.TargetServiceServer interface. type Service struct { - repoFn common.TargetRepoFactory - iamRepoFn common.IamRepoFactory + repoFn common.TargetRepoFactory + iamRepoFn common.IamRepoFactory + serversRepoFn common.ServersRepoFactory + sessionRepoFn common.SessionRepoFactory + staticHostRepoFn common.StaticRepoFactory + kmsCache *kms.Kms } // NewService returns a target service which handles target related requests to boundary. -func NewService(repoFn common.TargetRepoFactory, iamRepoFn common.IamRepoFactory) (Service, error) { +func NewService( + kmsCache *kms.Kms, + repoFn common.TargetRepoFactory, + iamRepoFn common.IamRepoFactory, + serversRepoFn common.ServersRepoFactory, + sessionRepoFn common.SessionRepoFactory, + staticHostRepoFn common.StaticRepoFactory) (Service, error) { if repoFn == nil { return Service{}, fmt.Errorf("nil target repository provided") } if iamRepoFn == nil { return Service{}, fmt.Errorf("nil iam repository provided") } - return Service{repoFn: repoFn, iamRepoFn: iamRepoFn}, nil + if serversRepoFn == nil { + return Service{}, fmt.Errorf("nil servers repository provided") + } + if sessionRepoFn == nil { + return Service{}, fmt.Errorf("nil session repository provided") + } + if staticHostRepoFn == nil { + return Service{}, fmt.Errorf("nil static host repository provided") + } + return Service{ + repoFn: repoFn, + iamRepoFn: iamRepoFn, + serversRepoFn: serversRepoFn, + sessionRepoFn: sessionRepoFn, + staticHostRepoFn: staticHostRepoFn, + kmsCache: kmsCache, + }, nil } var _ pbs.TargetServiceServer = Service{} @@ -84,6 +118,9 @@ func (s Service) GetTarget(ctx context.Context, req *pbs.GetTargetRequest) (*pbs if err != nil { return nil, err } + if u == nil { + return nil, nil + } u.Scope = authResults.Scope return &pbs.GetTargetResponse{Item: u}, nil } @@ -118,6 +155,9 @@ func (s Service) UpdateTarget(ctx context.Context, req *pbs.UpdateTargetRequest) if err != nil { return nil, err } + if u == nil { + return nil, nil + } u.Scope = authResults.Scope return &pbs.UpdateTargetResponse{Item: u}, nil } @@ -189,6 +229,182 @@ func (s Service) RemoveTargetHostSets(ctx context.Context, req *pbs.RemoveTarget return &pbs.RemoveTargetHostSetsResponse{Item: u}, nil } +func (s Service) AuthorizeSession(ctx context.Context, req *pbs.AuthorizeSessionRequest) (*pbs.AuthorizeSessionResponse, error) { + if err := validateAuthorizeRequest(req); err != nil { + return nil, err + } + authResults := s.authResult(ctx, req.GetId(), action.Authorize) + if authResults.Error != nil { + return nil, authResults.Error + } + // This could happen if, say, u_recovery was used or u_anon was granted. But + // don't allow it. It's one thing if grants give access to resources within + // Boundary, even if those could eventually be used to provide an unintended + // user access to a remote system. It's quite another to enable anonymous + // access directly to a remote system. + // + // Note that even if u_anon or u_auth are given grants we can still validate + // a token! So this is just checking that a valid token was provided. The + // actual reality of this works out to excluding: + // + // * True anonymous access (no token provided and u_anon) + // + // * u_recovery access (which is fine, recovery is meant for recovering + // system state, no real reason to allow it to then connect to systems) + if authResults.AuthTokenId == "" { + return nil, handlers.ForbiddenError() + } + + // Get the target information + repo, err := s.repoFn() + if err != nil { + return nil, err + } + t, hostSets, err := repo.LookupTarget(ctx, req.GetId()) + if err != nil { + if errors.Is(err, db.ErrRecordNotFound) { + return nil, nil + } + return nil, err + } + if t == nil { + return nil, nil + } + + // Instantiate some repos + sessionRepo, err := s.sessionRepoFn() + if err != nil { + return nil, err + } + serversRepo, err := s.serversRepoFn() + if err != nil { + return nil, err + } + + // First, fetch all available hosts. Unless one was chosen in the request, + // we will pick one at random. + type compoundHost struct { + hostSetId string + hostId string + } + + var chosenId compoundHost + requestedId := req.GetHostId() + staticHostRepo, err := s.staticHostRepoFn() + if err != nil { + return nil, err + } + + hostIds := make([]compoundHost, 0, len(hostSets)*10) + for _, tSet := range hostSets { + hsId := tSet.PublicId + switch host.SubtypeFromId(hsId) { + case host.StaticSubtype: + _, hosts, err := staticHostRepo.LookupSet(ctx, hsId) + if err != nil { + return nil, err + } + for _, host := range hosts { + compoundId := compoundHost{hostSetId: hsId, hostId: host.PublicId} + if host.PublicId == requestedId { + chosenId = compoundId + goto HOST_GATHERING_DONE + } + hostIds = append(hostIds, compoundId) + } + } + } + if requestedId != "" { + // We didn't find it + return nil, handlers.InvalidArgumentErrorf( + "Errors in provided fields.", + map[string]string{ + "host_id": "The requested host id is not available.", + }) + } + chosenId = hostIds[rand.Intn(len(hostIds))] + +HOST_GATHERING_DONE: + // Generate the endpoint URL + endpointUrl := &url.URL{ + Scheme: t.GetType(), + } + defaultPort := t.GetDefaultPort() + var endpointHost string + switch host.SubtypeFromId(chosenId.hostId) { + case host.StaticSubtype: + h, err := staticHostRepo.LookupHost(ctx, chosenId.hostId) + if err != nil { + return nil, fmt.Errorf("error looking up host: %w", err) + } + endpointHost = h.Address + if endpointHost == "" { + return nil, errors.New("host had empty address") + } + } + if defaultPort != 0 { + endpointUrl.Host = fmt.Sprintf("%s:%d", endpointHost, defaultPort) + } else { + endpointUrl.Host = endpointHost + } + + sessionComposition := session.ComposedOf{ + UserId: authResults.UserId, + HostId: chosenId.hostId, + TargetId: t.GetPublicId(), + HostSetId: chosenId.hostSetId, + AuthTokenId: authResults.AuthTokenId, + ScopeId: authResults.Scope.Id, + Endpoint: endpointUrl.String(), + } + + sess, err := session.New(sessionComposition) + if err != nil { + return nil, err + } + wrapper, err := s.kmsCache.GetWrapper(ctx, authResults.Scope.Id, kms.KeyPurposeSessions) + if err != nil { + return nil, err + } + sess, _, privKey, err := sessionRepo.CreateSession(ctx, wrapper, sess) + if err != nil { + return nil, err + } + + var workers []*pb.WorkerInfo + servers, err := serversRepo.ListServers(ctx, servers.ServerTypeWorker) + if err != nil { + return nil, err + } + for _, v := range servers { + workers = append(workers, &pb.WorkerInfo{Address: v.Address}) + } + + sad := &pb.SessionAuthorizationData{ + SessionId: sess.PublicId, + TargetId: t.GetPublicId(), + Scope: authResults.Scope, + CreatedTime: sess.CreateTime.GetTimestamp(), + Type: t.GetType(), + Certificate: sess.Certificate, + PrivateKey: privKey, + WorkerInfo: workers, + } + marshaledSad, err := proto.Marshal(sad) + if err != nil { + return nil, err + } + ret := &pb.SessionAuthorization{ + SessionId: sess.PublicId, + TargetId: t.GetPublicId(), + Scope: authResults.Scope, + CreatedTime: sess.CreateTime.GetTimestamp(), + Type: t.GetType(), + AuthorizationToken: base58.Encode(marshaledSad), + } + return &pbs.AuthorizeSessionResponse{Item: ret}, nil +} + func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Target, error) { repo, err := s.repoFn() if err != nil { @@ -197,12 +413,12 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Target, error) u, m, err := repo.LookupTarget(ctx, id) if err != nil { if errors.Is(err, db.ErrRecordNotFound) { - return nil, handlers.NotFoundErrorf("Target %q doesn't exist.", id) + return nil, nil } return nil, err } if u == nil { - return nil, handlers.NotFoundErrorf("Target %q doesn't exist.", id) + return nil, nil } return toProto(u, m) } @@ -272,7 +488,7 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st return nil, status.Errorf(codes.Internal, "Unable to update target: %v.", err) } if rowsUpdated == 0 { - return nil, handlers.NotFoundErrorf("Target %q doesn't exist.", id) + return nil, nil } return toProto(out, m) } @@ -490,7 +706,6 @@ func validateUpdateRequest(req *pbs.UpdateTargetRequest) error { badFields["name"] = "This field cannot be set to empty." } switch target.SubtypeFromType(req.GetItem().GetType()) { - case target.TcpSubType: tcpAttrs := &pb.TcpTargetAttributes{} if err := handlers.StructToProto(req.GetItem().GetAttributes(), tcpAttrs); err != nil { @@ -569,3 +784,21 @@ func validateRemoveRequest(req *pbs.RemoveTargetHostSetsRequest) error { } return nil } + +func validateAuthorizeRequest(req *pbs.AuthorizeSessionRequest) error { + badFields := map[string]string{} + if !handlers.ValidId(target.TcpTargetPrefix, req.GetId()) { + badFields["id"] = "Incorrectly formatted identifier." + } + if req.GetHostId() != "" { + switch host.SubtypeFromId(req.GetHostId()) { + case host.StaticSubtype: + default: + badFields["host_id"] = "Incorrectly formatted identifier." + } + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) + } + return nil +} diff --git a/internal/servers/controller/handlers/targets/target_service_test.go b/internal/servers/controller/handlers/targets/target_service_test.go index e9693b776..6a797368a 100644 --- a/internal/servers/controller/handlers/targets/target_service_test.go +++ b/internal/servers/controller/handlers/targets/target_service_test.go @@ -16,9 +16,13 @@ import ( "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" "github.com/hashicorp/boundary/internal/servers/controller/handlers/targets" + "github.com/hashicorp/boundary/internal/session" "github.com/hashicorp/boundary/internal/target" "github.com/hashicorp/boundary/internal/types/scope" + wrapping "github.com/hashicorp/go-kms-wrapping" + "github.com/jinzhu/gorm" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/genproto/protobuf/field_mask" @@ -30,6 +34,26 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) +func testService(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper) (targets.Service, error) { + rw := db.New(conn) + repoFn := func() (*target.Repository, error) { + return target.NewRepository(rw, rw, kms) + } + iamRepoFn := func() (*iam.Repository, error) { + return iam.TestRepo(t, conn, wrapper), nil + } + serversRepoFn := func() (*servers.Repository, error) { + return servers.NewRepository(rw, rw, kms) + } + sessionRepoFn := func() (*session.Repository, error) { + return session.NewRepository(rw, rw, kms) + } + staticHostRepoFn := func() (*static.Repository, error) { + return static.NewRepository(rw, rw, kms) + } + return targets.NewService(kms, repoFn, iamRepoFn, serversRepoFn, sessionRepoFn, staticHostRepoFn) +} + func TestGet(t *testing.T) { t.Parallel() conn, _ := db.TestSetup(t, "postgres") @@ -38,13 +62,6 @@ func TestGet(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) @@ -100,7 +117,7 @@ func TestGet(t *testing.T) { t.Run(tc.name, func(t *testing.T) { assert := assert.New(t) - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Couldn't create a new host set service.") got, gErr := s.GetTarget(auth.DisabledAuthTestContext(auth.WithScopeId(proj.GetPublicId())), tc.req) @@ -119,13 +136,6 @@ func TestList(t *testing.T) { wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } _, projNoTar := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] @@ -170,7 +180,7 @@ func TestList(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { assert, require := assert.New(t), require.New(t) - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(err, "Couldn't create new host set service.") got, gErr := s.ListTargets(auth.DisabledAuthTestContext(auth.WithScopeId(tc.scopeId)), &pbs.ListTargetsRequest{ScopeId: tc.scopeId}) @@ -189,15 +199,7 @@ func TestDelete(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) tar := target.TestTcpTarget(t, conn, proj.GetPublicId(), "test") - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } - - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Couldn't create a new target service.") cases := []struct { @@ -251,16 +253,9 @@ func TestDelete_twice(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } tar := target.TestTcpTarget(t, conn, proj.GetPublicId(), "test") - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Couldn't create a new target service.") req := &pbs.DeleteTargetRequest{ Id: tar.GetPublicId(), @@ -281,14 +276,6 @@ func TestCreate(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } - cases := []struct { name string req *pbs.CreateTargetRequest @@ -379,7 +366,7 @@ func TestCreate(t *testing.T) { t.Run(tc.name, func(t *testing.T) { assert, require := assert.New(t), require.New(t) - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(err, "Failed to create a new host set service.") got, gErr := s.CreateTarget(auth.DisabledAuthTestContext(auth.WithScopeId(proj.GetPublicId())), tc.req) @@ -409,9 +396,6 @@ func TestUpdate(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } rw := db.New(conn) repoFn := func() (*target.Repository, error) { return target.NewRepository(rw, rw, kms) @@ -449,7 +433,7 @@ func TestUpdate(t *testing.T) { Id: tar.GetPublicId(), } - tested, err := targets.NewService(repoFn, iamRepoFn) + tested, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Failed to create a new host set service.") cases := []struct { @@ -736,15 +720,6 @@ func TestUpdate(t *testing.T) { req := proto.Clone(toMerge).(*pbs.UpdateTargetRequest) proto.Merge(req, tc.req) - // Test some bad versions - req.Item.Version = version + 2 - _, gErr := tested.UpdateTarget(auth.DisabledAuthTestContext(auth.WithScopeId(proj.GetPublicId())), req) - require.Error(gErr) - req.Item.Version = version - 1 - _, gErr = tested.UpdateTarget(auth.DisabledAuthTestContext(auth.WithScopeId(proj.GetPublicId())), req) - require.Error(gErr) - req.Item.Version = version - got, gErr := tested.UpdateTarget(auth.DisabledAuthTestContext(auth.WithScopeId(proj.GetPublicId())), req) assert.Equal(tc.errCode, status.Code(gErr), "UpdateTarget(%+v) got error %v, wanted %v", req, gErr, tc.errCode) @@ -778,14 +753,7 @@ func TestAddTargetHostSets(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Error when getting new target service.") hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] @@ -878,14 +846,7 @@ func TestSetTargetHostSets(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - rw := db.New(conn) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Error when getting new host set service.") hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] @@ -972,14 +933,7 @@ func TestRemoveTargetHostSets(t *testing.T) { _, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - iamRepoFn := func() (*iam.Repository, error) { - return iam.TestRepo(t, conn, wrapper), nil - } - rw := db.New(conn) - repoFn := func() (*target.Repository, error) { - return target.NewRepository(rw, rw, kms) - } - s, err := targets.NewService(repoFn, iamRepoFn) + s, err := testService(t, conn, kms, wrapper) require.NoError(t, err, "Error when getting new host set service.") hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] diff --git a/internal/servers/controller/handlers/workers/worker_service.go b/internal/servers/controller/handlers/workers/worker_service.go index 8ab8cb8d0..5c7788d52 100644 --- a/internal/servers/controller/handlers/workers/worker_service.go +++ b/internal/servers/controller/handlers/workers/worker_service.go @@ -2,10 +2,11 @@ package workers import ( "context" + "encoding/base64" "sync" "time" - pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + "github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets" pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/servers/controller/common" @@ -17,22 +18,27 @@ import ( ) type workerServiceServer struct { - logger hclog.Logger - repoFn common.ServersRepoFactory - updateTimes *sync.Map - kms *kms.Kms - jobMap *sync.Map - jobCancelMap *sync.Map + logger hclog.Logger + serversRepoFn common.ServersRepoFactory + sessionRepoFn common.SessionRepoFactory + updateTimes *sync.Map + kms *kms.Kms + jobCancelMap *sync.Map } -func NewWorkerServiceServer(logger hclog.Logger, repoFn common.ServersRepoFactory, updateTimes *sync.Map, kms *kms.Kms, jobMap *sync.Map) *workerServiceServer { +func NewWorkerServiceServer( + logger hclog.Logger, + serversRepoFn common.ServersRepoFactory, + sessionRepoFn common.SessionRepoFactory, + updateTimes *sync.Map, + kms *kms.Kms) *workerServiceServer { return &workerServiceServer{ - logger: logger, - repoFn: repoFn, - updateTimes: updateTimes, - kms: kms, - jobMap: jobMap, - jobCancelMap: new(sync.Map), + logger: logger, + serversRepoFn: serversRepoFn, + sessionRepoFn: sessionRepoFn, + updateTimes: updateTimes, + kms: kms, + jobCancelMap: new(sync.Map), } } @@ -42,7 +48,7 @@ var _ pbs.ServerCoordinationServiceServer = &workerServiceServer{} func (ws *workerServiceServer) Status(ctx context.Context, req *pbs.StatusRequest) (*pbs.StatusResponse, error) { ws.logger.Trace("got status request from worker", "name", req.Worker.Name, "address", req.Worker.Address, "jobs", req.GetJobs()) ws.updateTimes.Store(req.Worker.Name, time.Now()) - repo, err := ws.repoFn() + repo, err := ws.serversRepoFn() if err != nil { ws.logger.Error("error getting servers repo", "error", err) return &pbs.StatusResponse{}, status.Errorf(codes.Internal, "Error aqcuiring repo to store worker status: %v", err) @@ -72,15 +78,31 @@ func (ws *workerServiceServer) Status(ctx context.Context, req *pbs.StatusReques return ret, nil } -func (ws *workerServiceServer) GetSession(ctx context.Context, req *pbs.GetSessionRequest) (*pbs.GetSessionResponse, error) { - ws.logger.Trace("got validate session request from worker", "job_id", req.GetId()) +func (ws *workerServiceServer) LookupSession(ctx context.Context, req *pbs.LookupSessionRequest) (*pbs.LookupSessionResponse, error) { + ws.logger.Trace("got validate session request from worker", "session_id", req.GetSessionId()) - // Look up the job info - storedSessionInfo, loaded := ws.jobMap.LoadAndDelete(req.GetId()) - if !loaded { - return nil, status.Errorf(codes.PermissionDenied, "Unknown job ID: %v", req.GetId()) + sessRepo, err := ws.sessionRepoFn() + if err != nil { + return nil, status.Errorf(codes.Internal, "error getting session repo: %v", err) + } + + sessionInfo, _, err := sessRepo.LookupSession(ctx, req.GetSessionId()) + if err != nil { + return nil, status.Errorf(codes.Internal, "error looking up session: %v", err) + } + if sessionInfo == nil { + return nil, status.Error(codes.PermissionDenied, "Unknown session ID.") + } + + resp := &pbs.LookupSessionResponse{ + Authorization: &targets.SessionAuthorizationData{ + SessionId: sessionInfo.GetPublicId(), + Certificate: sessionInfo.Certificate, + }, + Version: sessionInfo.Version, + TofuToken: base64.StdEncoding.EncodeToString(sessionInfo.TofuToken), + Endpoint: sessionInfo.Endpoint, } - sessionInfo := storedSessionInfo.(*pb.Session) wrapper, err := ws.kms.GetWrapper(ctx, sessionInfo.ScopeId, kms.KeyPurposeSessions) if err != nil { @@ -89,23 +111,35 @@ func (ws *workerServiceServer) GetSession(ctx context.Context, req *pbs.GetSessi // Derive the private key, which should match. Deriving on both ends allows // us to not store it in the DB. - _, privKey, err := session.DeriveED25519Key(wrapper, sessionInfo.GetUserId(), req.GetId()) + _, resp.Authorization.PrivateKey, err = session.DeriveED25519Key(wrapper, sessionInfo.UserId, sessionInfo.GetPublicId()) if err != nil { return nil, status.Errorf(codes.Internal, "Error deriving session key: %v", err) } - if sessionInfo.ExpirationTime.GetSeconds() > 0 { - timeDiff := time.Until(sessionInfo.GetExpirationTime().AsTime()) - if timeDiff < 0 { - return nil, status.Errorf(codes.OutOfRange, "Session has already expired") - } - defer func() { - time.AfterFunc(timeDiff, func() { - ws.jobCancelMap.Store(req.GetId(), true) - }) - }() + return resp, nil +} + +func (ws *workerServiceServer) ActivateSession(ctx context.Context, req *pbs.ActivateSessionRequest) (*pbs.ActivateSessionResponse, error) { + ws.logger.Trace("got activate session request from worker", "session_id", req.GetSessionId()) + + sessRepo, err := ws.sessionRepoFn() + if err != nil { + return nil, status.Errorf(codes.Internal, "error getting session repo: %v", err) } - sessionInfo.PrivateKey = privKey - return &pbs.GetSessionResponse{Session: sessionInfo}, nil + sessionInfo, _, err := sessRepo.ActivateSession( + ctx, + req.GetSessionId(), + req.GetVersion(), + req.GetWorkerId(), + resource.Worker.String(), + []byte(req.GetTofuToken())) + if err != nil { + return nil, status.Errorf(codes.Internal, "error looking up session: %v", err) + } + if sessionInfo == nil { + return nil, status.Error(codes.PermissionDenied, "Unknown session ID.") + } + + return &pbs.ActivateSessionResponse{}, nil } diff --git a/internal/servers/controller/listeners.go b/internal/servers/controller/listeners.go index 249942c6c..cd4b56a25 100644 --- a/internal/servers/controller/listeners.go +++ b/internal/servers/controller/listeners.go @@ -120,7 +120,7 @@ func (c *Controller) startListeners() error { grpc.MaxRecvMsgSize(math.MaxInt32), grpc.MaxSendMsgSize(math.MaxInt32), ) - workerService := workers.NewWorkerServiceServer(c.logger.Named("worker-handler"), c.ServersRepoFn, c.workerStatusUpdateTimes, c.kms, c.jobMap) + workerService := workers.NewWorkerServiceServer(c.logger.Named("worker-handler"), c.ServersRepoFn, c.SessionRepoFn, c.workerStatusUpdateTimes, c.kms) pbs.RegisterServerCoordinationServiceServer(workerServer, workerService) pbs.RegisterSessionServiceServer(workerServer, workerService) diff --git a/internal/servers/worker/controller_connection.go b/internal/servers/worker/controller_connection.go index 7328c78d1..54eb3ccd5 100644 --- a/internal/servers/worker/controller_connection.go +++ b/internal/servers/worker/controller_connection.go @@ -111,8 +111,8 @@ func (w *Worker) createClientConn(addr string) error { return fmt.Errorf("error dialing controller for worker auth: %w", err) } - client := pbs.NewServerCoordinationServiceClient(cc) - w.controllerConn.Store(client) + w.controllerStatusConn.Store(pbs.NewServerCoordinationServiceClient(cc)) + w.controllerSessionConn.Store(pbs.NewSessionServiceClient(cc)) w.logger.Info("connected to controller", "address", addr) return nil diff --git a/internal/servers/worker/handler.go b/internal/servers/worker/handler.go index 6d42bd95b..fbe4bb21f 100644 --- a/internal/servers/worker/handler.go +++ b/internal/servers/worker/handler.go @@ -6,7 +6,7 @@ import ( "time" "github.com/hashicorp/boundary/globals" - pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + "github.com/hashicorp/boundary/internal/gen/controller/servers/services" "github.com/hashicorp/boundary/internal/proxy" "github.com/hashicorp/shared-secure-libs/configutil" "nhooyr.io/websocket" @@ -37,15 +37,19 @@ func (w *Worker) handleProxy() http.HandlerFunc { wr.WriteHeader(http.StatusInternalServerError) return } - jobId := r.TLS.ServerName + sessionId := r.TLS.ServerName - jobInfoRaw, valid := w.jobInfoMap.LoadAndDelete(jobId) + w.logger.Trace("received TLS connection") + + sessionInfoRaw, valid := w.sessionInfoMap.LoadAndDelete(sessionId) if !valid { - w.logger.Error("job not found in info map", "job_id", jobId) + w.logger.Error("session not found in info map", "session_id", sessionId) wr.WriteHeader(http.StatusInternalServerError) return } - jobInfo := jobInfoRaw.(*pb.Session) + sessionInfo := sessionInfoRaw.(*services.LookupSessionResponse) + + w.logger.Trace("found session in session info map") opts := &websocket.AcceptOptions{ Subprotocols: []string{globals.TcpProxyV1}, @@ -59,31 +63,56 @@ func (w *Worker) handleProxy() http.HandlerFunc { // Later calls will cause this to noop if they return a different status defer conn.Close(websocket.StatusNormalClosure, "done") + w.logger.Trace("websocket upgrade done") + connCtx, connCancel := context.WithCancel(r.Context()) - w.cancellationMap.Store(jobId, connCancel) + w.cancellationMap.Store(sessionId, connCancel) defer func() { - cancel, loaded := w.cancellationMap.LoadAndDelete(jobId) + cancel, loaded := w.cancellationMap.LoadAndDelete(sessionId) if !loaded { return } cancel.(context.CancelFunc)() }() - var handshake proxy.Handshake + var handshake proxy.ClientHandshake if err := wspb.Read(connCtx, conn, &handshake); err != nil { - w.logger.Error("error reading nonce from client", "error", err) - wr.WriteHeader(http.StatusBadRequest) + w.logger.Error("error reading handshake from client", "error", err) + conn.Close(websocket.StatusPolicyViolation, "invalid handshake received") return } if len(handshake.GetTofuToken()) < 20 { w.logger.Error("invalid tofu token") - wr.WriteHeader(http.StatusBadRequest) + conn.Close(websocket.StatusUnsupportedData, "invalid tofu token") + return + } + + w.logger.Trace("proxy handshake finished") + + if sessionInfo.TofuToken != "" { + if sessionInfo.TofuToken != handshake.GetTofuToken() { + w.logger.Error("WARNING: mismatched tofu token", "session_id", sessionId) + conn.Close(websocket.StatusPolicyViolation, "tofu token not allowed") + return + } + } else { + w.logger.Trace("activating session") + if err := w.activateSession(r.Context(), handshake.GetTofuToken(), sessionInfo); err != nil { + w.logger.Error("unable to validate session", "error", err) + conn.Close(websocket.StatusInternalError, "unable to activate session") + return + } + } + + if err := wspb.Write(connCtx, conn, &proxy.HandshakeResult{}); err != nil { + w.logger.Error("error sending handshake result to client", "error", err) + conn.Close(websocket.StatusProtocolError, "unable to send handshake result") return } switch conn.Subprotocol() { case globals.TcpProxyV1: - w.handleTcpProxyV1(connCtx, conn, jobInfo) + w.handleTcpProxyV1(connCtx, conn, sessionInfo) default: conn.Close(websocket.StatusProtocolError, "unsupported-protocol") return diff --git a/internal/servers/worker/job.go b/internal/servers/worker/job.go deleted file mode 100644 index bd0a3eb98..000000000 --- a/internal/servers/worker/job.go +++ /dev/null @@ -1,84 +0,0 @@ -package worker - -import ( - "context" - "crypto/ed25519" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "strings" - "time" - - pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" -) - -const ( - validateSessionTimeout = 90 * time.Second -) - -func (w *Worker) getJobTls(hello *tls.ClientHelloInfo) (*tls.Config, error) { - var jobId string - switch { - case strings.HasPrefix(hello.ServerName, "s_"): - jobId = hello.ServerName - default: - return nil, fmt.Errorf("could not find job ID in SNI") - } - - rawConn := w.controllerConn.Load() - if rawConn == nil { - return nil, errors.New("could not get a controller client") - } - conn, ok := rawConn.(pbs.SessionServiceClient) - if !ok { - return nil, errors.New("could not cast atomic controller client to the real thing") - } - if conn == nil { - return nil, errors.New("controller client is nil") - } - - timeoutContext, cancel := context.WithTimeout(w.baseContext, validateSessionTimeout) - defer cancel() - - resp, err := conn.GetSession(timeoutContext, &pbs.GetSessionRequest{ - Id: jobId, - }) - if err != nil { - return nil, fmt.Errorf("error validating session: %w", err) - } - - parsedCert, err := x509.ParseCertificate(resp.GetSession().GetCertificate()) - if err != nil { - return nil, fmt.Errorf("error parsing session certificate: %w", err) - } - - if len(parsedCert.DNSNames) != 1 { - return nil, fmt.Errorf("invalid length of DNS names (%d) in parsed certificate", len(parsedCert.DNSNames)) - } - - certPool := x509.NewCertPool() - certPool.AddCert(parsedCert) - - tlsConf := &tls.Config{ - Certificates: []tls.Certificate{ - { - Certificate: [][]byte{resp.GetSession().GetCertificate()}, - PrivateKey: ed25519.PrivateKey(resp.GetSession().GetPrivateKey()), - Leaf: parsedCert, - }, - }, - ServerName: parsedCert.DNSNames[0], - ClientAuth: tls.RequireAndVerifyClientCert, - ClientCAs: certPool, - MinVersion: tls.VersionTLS13, - } - - // TODO: Periodicially clean this up. We can't rely on things in here but - // not in cancellation because they could be on the way to being - // established. However, since cert lifetimes are short, we can simply range - // through and remove values that are expired. - w.jobInfoMap.Store(jobId, resp) - - return tlsConf, nil -} diff --git a/internal/servers/worker/listeners.go b/internal/servers/worker/listeners.go index f46ef46de..9a4b96331 100644 --- a/internal/servers/worker/listeners.go +++ b/internal/servers/worker/listeners.go @@ -70,7 +70,7 @@ func (w *Worker) startListeners() error { ln.Mux.UnregisterProto(alpnmux.DefaultProto) ln.Mux.UnregisterProto(alpnmux.NoProto) l, err := ln.Mux.RegisterProto(alpnmux.DefaultProto, &tls.Config{ - GetConfigForClient: w.getJobTls, + GetConfigForClient: w.getSessionTls, }) if err != nil { return fmt.Errorf("error getting tls listener: %w", err) diff --git a/internal/servers/worker/session.go b/internal/servers/worker/session.go new file mode 100644 index 000000000..abbaae078 --- /dev/null +++ b/internal/servers/worker/session.go @@ -0,0 +1,117 @@ +package worker + +import ( + "context" + "crypto/ed25519" + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "strings" + "time" + + "github.com/hashicorp/boundary/internal/gen/controller/servers/services" + pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" +) + +const ( + validateSessionTimeout = 90 * time.Second +) + +func (w *Worker) getSessionTls(hello *tls.ClientHelloInfo) (*tls.Config, error) { + var sessionId string + switch { + case strings.HasPrefix(hello.ServerName, "s_"): + w.logger.Trace("got valid session in SNI", "session_id", hello.ServerName) + sessionId = hello.ServerName + default: + w.logger.Trace("invalid session in SNI", "session_id", hello.ServerName) + return nil, fmt.Errorf("could not find session ID in SNI") + } + + rawConn := w.controllerSessionConn.Load() + if rawConn == nil { + w.logger.Trace("could not get a controller client", "session_id", sessionId) + return nil, errors.New("could not get a controller client") + } + conn, ok := rawConn.(pbs.SessionServiceClient) + if !ok { + w.logger.Trace("could not cast controller client to the real thing", "session_id", sessionId) + return nil, errors.New("could not cast atomic controller client to the real thing") + } + if conn == nil { + w.logger.Trace("controller client is nil", "session_id", sessionId) + return nil, errors.New("controller client is nil") + } + + timeoutContext, cancel := context.WithTimeout(w.baseContext, validateSessionTimeout) + defer cancel() + + w.logger.Trace("looking up session", "session_id", sessionId) + resp, err := conn.LookupSession(timeoutContext, &pbs.LookupSessionRequest{ + SessionId: sessionId, + }) + if err != nil { + return nil, fmt.Errorf("error validating session: %w", err) + } + + parsedCert, err := x509.ParseCertificate(resp.GetAuthorization().Certificate) + if err != nil { + return nil, fmt.Errorf("error parsing session certificate: %w", err) + } + + if len(parsedCert.DNSNames) != 1 { + return nil, fmt.Errorf("invalid length of DNS names (%d) in parsed certificate", len(parsedCert.DNSNames)) + } + + certPool := x509.NewCertPool() + certPool.AddCert(parsedCert) + + tlsConf := &tls.Config{ + Certificates: []tls.Certificate{ + { + Certificate: [][]byte{resp.GetAuthorization().Certificate}, + PrivateKey: ed25519.PrivateKey(resp.GetAuthorization().PrivateKey), + Leaf: parsedCert, + }, + }, + ServerName: parsedCert.DNSNames[0], + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: certPool, + MinVersion: tls.VersionTLS13, + } + + // TODO: Periodicially clean this up. We can't rely on things in here but + // not in cancellation because they could be on the way to being + // established. However, since cert lifetimes are short, we can simply range + // through and remove values that are expired. + w.sessionInfoMap.Store(sessionId, resp) + + w.logger.Trace("returning TLS configuration", "session_id", sessionId) + return tlsConf, nil +} + +func (w *Worker) activateSession(ctx context.Context, tofuToken string, sess *services.LookupSessionResponse) error { + rawConn := w.controllerSessionConn.Load() + if rawConn == nil { + return errors.New("could not get a controller client") + } + conn, ok := rawConn.(pbs.SessionServiceClient) + if !ok { + return errors.New("could not cast atomic controller client to the real thing") + } + if conn == nil { + return errors.New("controller client is nil") + } + + _, err := conn.ActivateSession(ctx, &pbs.ActivateSessionRequest{ + SessionId: sess.GetAuthorization().GetSessionId(), + TofuToken: tofuToken, + Version: sess.GetVersion(), + WorkerId: w.conf.RawConfig.Worker.Name, + }) + if err != nil { + return fmt.Errorf("error activating session: %w", err) + } + return nil +} diff --git a/internal/servers/worker/status.go b/internal/servers/worker/status.go index 1e83cd626..36092e01b 100644 --- a/internal/servers/worker/status.go +++ b/internal/servers/worker/status.go @@ -53,7 +53,7 @@ func (w *Worker) startStatusTicking(cancelCtx context.Context) { }) return true }) - client := w.controllerConn.Load().(pbs.ServerCoordinationServiceClient) + client := w.controllerStatusConn.Load().(pbs.ServerCoordinationServiceClient) result, err := client.Status(cancelCtx, &pbs.StatusRequest{ Jobs: activeJobs, Worker: &servers.Server{ diff --git a/internal/servers/worker/tcp_proxy.go b/internal/servers/worker/tcp_proxy.go index 086c59aee..da5c777f6 100644 --- a/internal/servers/worker/tcp_proxy.go +++ b/internal/servers/worker/tcp_proxy.go @@ -4,16 +4,29 @@ import ( "context" "io" "net" + "net/url" "sync" - pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions" + "github.com/hashicorp/boundary/internal/gen/controller/servers/services" "nhooyr.io/websocket" ) -func (w *Worker) handleTcpProxyV1(jobCtx context.Context, conn *websocket.Conn, jobInfo *pb.Session) { - remoteConn, err := net.Dial("tcp", jobInfo.Endpoint) +func (w *Worker) handleTcpProxyV1(connCtx context.Context, conn *websocket.Conn, sessionInfo *services.LookupSessionResponse) { + sessionId := sessionInfo.GetAuthorization().GetSessionId() + sessionUrl, err := url.Parse(sessionInfo.Endpoint) if err != nil { - w.logger.Error("error dialing endpoint", "error", err, "endpoint", jobInfo.Endpoint) + w.logger.Error("error parsing endpoint information", "error", err, "session_id", sessionId, "endpoint", sessionInfo.Endpoint) + conn.Close(websocket.StatusInternalError, "cannot parse endpoint url") + return + } + if sessionUrl.Scheme != "tcp" { + w.logger.Error("invalid scheme for tcp proxy", "error", err, "session_id", sessionId, "endpoint", sessionInfo.Endpoint) + conn.Close(websocket.StatusInternalError, "invalid scheme for type") + return + } + remoteConn, err := net.Dial("tcp", sessionUrl.Host) + if err != nil { + w.logger.Error("error dialing endpoint", "error", err, "endpoint", sessionInfo.Endpoint) conn.Close(websocket.StatusInternalError, "endpoint-dialing") return } @@ -21,7 +34,7 @@ func (w *Worker) handleTcpProxyV1(jobCtx context.Context, conn *websocket.Conn, tcpRemoteConn := remoteConn.(*net.TCPConn) // Get a wrapped net.Conn so we can use io.Copy - netConn := websocket.NetConn(jobCtx, conn, websocket.MessageBinary) + netConn := websocket.NetConn(connCtx, conn, websocket.MessageBinary) connWg := new(sync.WaitGroup) connWg.Add(2) diff --git a/internal/servers/worker/worker.go b/internal/servers/worker/worker.go index 641748de5..6e6d55e4b 100644 --- a/internal/servers/worker/worker.go +++ b/internal/servers/worker/worker.go @@ -24,27 +24,29 @@ type Worker struct { baseCancel context.CancelFunc started ua.Bool - controllerConn *atomic.Value - lastStatusSuccess *atomic.Value + controllerStatusConn *atomic.Value + lastStatusSuccess *atomic.Value listeningAddress string controllerResolver *atomic.Value controllerResolverCleanup *atomic.Value - jobInfoMap *sync.Map - cancellationMap *sync.Map + controllerSessionConn *atomic.Value + sessionInfoMap *sync.Map + cancellationMap *sync.Map } func New(conf *Config) (*Worker, error) { w := &Worker{ conf: conf, logger: conf.Logger.Named("worker"), - controllerConn: new(atomic.Value), + controllerStatusConn: new(atomic.Value), lastStatusSuccess: new(atomic.Value), controllerResolver: new(atomic.Value), controllerResolverCleanup: new(atomic.Value), - jobInfoMap: new(sync.Map), + controllerSessionConn: new(atomic.Value), + sessionInfoMap: new(sync.Map), cancellationMap: new(sync.Map), } diff --git a/internal/session/repository_session.go b/internal/session/repository_session.go index 9d5e50c0e..fa9eea4e5 100644 --- a/internal/session/repository_session.go +++ b/internal/session/repository_session.go @@ -3,6 +3,7 @@ package session import ( "context" "crypto/ed25519" + "crypto/subtle" "errors" "fmt" "strings" @@ -45,10 +46,10 @@ func (r *Repository) CreateSession(ctx context.Context, sessionWrapper wrapping. return nil, nil, nil, fmt.Errorf("create session: scope id is empty: %w", db.ErrInvalidParameter) } if newSession.ServerId != "" { - return nil, nil, nil, fmt.Errorf("create session: server id must empty: %w", db.ErrInvalidParameter) + return nil, nil, nil, fmt.Errorf("create session: server id must be empty: %w", db.ErrInvalidParameter) } if newSession.ServerType != "" { - return nil, nil, nil, fmt.Errorf("create session: server type must empty: %w", db.ErrInvalidParameter) + return nil, nil, nil, fmt.Errorf("create session: server type must be empty: %w", db.ErrInvalidParameter) } if newSession.CtTofuToken != nil { return nil, nil, nil, fmt.Errorf("create session: ct must be empty: %w", db.ErrInvalidParameter) @@ -391,7 +392,7 @@ func (r *Repository) CloseConnections(ctx context.Context, closeWith []CloseWith // was cancelled or terminated. func (r *Repository) ActivateSession(ctx context.Context, sessionId string, sessionVersion uint32, serverId, serverType string, tofuToken []byte) (*Session, []*State, error) { if sessionId == "" { - return nil, nil, fmt.Errorf("activate session: missing session id %w", db.ErrInvalidParameter) + return nil, nil, fmt.Errorf("activate session: missing session id: %w", db.ErrInvalidParameter) } if sessionVersion == 0 { return nil, nil, fmt.Errorf("activate session: version cannot be zero: %w", db.ErrInvalidParameter) @@ -402,6 +403,10 @@ func (r *Repository) ActivateSession(ctx context.Context, sessionId string, sess if serverType == "" { return nil, nil, fmt.Errorf("activate session: missing server type: %w", db.ErrInvalidParameter) } + if len(tofuToken) == 0 { + return nil, nil, fmt.Errorf("activate session: missing tofu token: %w", db.ErrInvalidParameter) + } + updatedSession := AllocSession() updatedSession.PublicId = sessionId var returnedStates []*State @@ -420,12 +425,16 @@ func (r *Repository) ActivateSession(ctx context.Context, sessionId string, sess foundSession := AllocSession() foundSession.PublicId = sessionId if err := reader.LookupById(ctx, &foundSession); err != nil { - return fmt.Errorf("lookup session: failed %w for %s", err, sessionId) + return fmt.Errorf("lookup session: failed for %s: %w", sessionId, err) } databaseWrapper, err := r.kms.GetWrapper(ctx, foundSession.ScopeId, kms.KeyPurposeDatabase) if err != nil { return fmt.Errorf("unable to get database wrapper: %w", err) } + if len(foundSession.TofuToken) > 0 && subtle.ConstantTimeCompare(foundSession.TofuToken, tofuToken) != 1 { + return fmt.Errorf("tofu token mismatch") + } + updatedSession.TofuToken = tofuToken updatedSession.ServerId = serverId updatedSession.ServerType = serverType diff --git a/internal/session/repository_session_test.go b/internal/session/repository_session_test.go index e9ee11643..08fca0a4a 100644 --- a/internal/session/repository_session_test.go +++ b/internal/session/repository_session_test.go @@ -243,6 +243,7 @@ func TestRepository_CreateSession(t *testing.T) { HostSetId: tt.args.composedOf.HostSetId, AuthTokenId: tt.args.composedOf.AuthTokenId, ScopeId: tt.args.composedOf.ScopeId, + Endpoint: "tcp://127.0.0.1:22", } ses, st, privKey, err := repo.CreateSession(context.Background(), wrapper, s) if tt.wantErr { diff --git a/internal/session/session.go b/internal/session/session.go index b441910b4..f6b8745cc 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -36,6 +36,10 @@ type ComposedOf struct { AuthTokenId string // ScopeId of the session ScopeId string + // Endpoint. This is generated by the target, but is not stored in the + // warehouse as the worker may need to e.g. resolve DNS. This is to round + // trip the information to the worker when it validates a session. + Endpoint string } // Session contains information about a user's session with a target @@ -76,6 +80,8 @@ type Session struct { UpdateTime *timestamp.Timestamp `json:"update_time,omitempty" gorm:"default:current_timestamp"` // Version for the session Version uint32 `json:"version,omitempty" gorm:"default:null"` + // Endpoint + Endpoint string `json:"-" gorm:"default:null"` // key_id is the key ID that was used for the encryption operation. It can be // used to identify a specific version of the key needed to decrypt the value, @@ -105,6 +111,7 @@ func New(c ComposedOf, opt ...Option) (*Session, error) { HostSetId: c.HostSetId, AuthTokenId: c.AuthTokenId, ScopeId: c.ScopeId, + Endpoint: c.Endpoint, ExpirationTime: opts.withExpirationTime, } if err := s.validateNewSession("new session:"); err != nil { @@ -132,6 +139,7 @@ func (s *Session) Clone() interface{} { ScopeId: s.ScopeId, TerminationReason: s.TerminationReason, Version: s.Version, + Endpoint: s.Endpoint, } if s.TofuToken != nil { clone.TofuToken = make([]byte, len(s.TofuToken)) @@ -207,6 +215,8 @@ func (s *Session) VetForWrite(ctx context.Context, r db.Reader, opType db.OpType return fmt.Errorf("session vet for write: create time is immutable: %w", db.ErrInvalidParameter) case contains(opts.WithFieldMaskPaths, "UpdateTime"): return fmt.Errorf("session vet for write: update time is immutable: %w", db.ErrInvalidParameter) + case contains(opts.WithFieldMaskPaths, "Endpoint"): + return fmt.Errorf("session vet for write: endpoint is immutable: %w", db.ErrInvalidParameter) case contains(opts.WithFieldMaskPaths, "TerminationReason"): if _, err := convertToReason(s.TerminationReason); err != nil { return fmt.Errorf("session vet for write: termination reason '%s' is invalid: %w", s.TerminationReason, db.ErrInvalidParameter) @@ -251,6 +261,9 @@ func (s *Session) validateNewSession(errorPrefix string) error { if s.ScopeId == "" { return fmt.Errorf("%s missing scope id: %w", errorPrefix, db.ErrInvalidParameter) } + if s.Endpoint == "" { + return fmt.Errorf("%s missing endpoint: %w", errorPrefix, db.ErrInvalidParameter) + } if s.TerminationReason != "" { return fmt.Errorf("%s termination reason must be empty: %w", errorPrefix, db.ErrInvalidParameter) } diff --git a/internal/session/session_test.go b/internal/session/session_test.go index 44f7ad17b..b98c15b96 100644 --- a/internal/session/session_test.go +++ b/internal/session/session_test.go @@ -51,6 +51,7 @@ func TestSession_Create(t *testing.T) { HostSetId: composedOf.HostSetId, AuthTokenId: composedOf.AuthTokenId, ScopeId: composedOf.ScopeId, + Endpoint: "tcp://127.0.0.1:22", }, create: true, }, diff --git a/internal/session/testing.go b/internal/session/testing.go index 423ccf0d9..dcb7e4465 100644 --- a/internal/session/testing.go +++ b/internal/session/testing.go @@ -133,6 +133,7 @@ func TestSessionParams(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, ia HostSetId: sets[0].PublicId, AuthTokenId: at.PublicId, ScopeId: tcpTarget.ScopeId, + Endpoint: "tcp://127.0.0.1:22", } } diff --git a/internal/target/target.go b/internal/target/target.go index fae03b5bc..4d6146b2c 100644 --- a/internal/target/target.go +++ b/internal/target/target.go @@ -16,6 +16,7 @@ type Target interface { GetName() string GetDescription() string GetVersion() uint32 + GetType() string GetCreateTime() *timestamp.Timestamp GetUpdateTime() *timestamp.Timestamp oplog(op oplog.OpType) oplog.Metadata diff --git a/internal/target/tcp_target.go b/internal/target/tcp_target.go index 6a36c37f0..2f08bdfb7 100644 --- a/internal/target/tcp_target.go +++ b/internal/target/tcp_target.go @@ -97,3 +97,7 @@ func (t *TcpTarget) oplog(op oplog.OpType) oplog.Metadata { } return metadata } + +func (t TcpTarget) GetType() string { + return "tcp" +} diff --git a/internal/types/action/action.go b/internal/types/action/action.go index f8fdfb320..afdf914a2 100644 --- a/internal/types/action/action.go +++ b/internal/types/action/action.go @@ -14,7 +14,7 @@ const ( Delete Type = 5 Authenticate Type = 6 All Type = 7 - Connect Type = 8 + Authorize Type = 8 AddGrants Type = 9 RemoveGrants Type = 10 SetGrants Type = 11 @@ -43,7 +43,7 @@ var Map = map[string]Type{ Delete.String(): Delete, Authenticate.String(): Authenticate, All.String(): All, - Connect.String(): Connect, + Authorize.String(): Authorize, AddGrants.String(): AddGrants, RemoveGrants.String(): RemoveGrants, SetGrants.String(): SetGrants, @@ -74,7 +74,7 @@ func (a Type) String() string { "delete", "authenticate", "*", - "connect", + "authorize", "add-grants", "remove-grants", "set-grants", diff --git a/internal/types/action/action_test.go b/internal/types/action/action_test.go index bfaf59d14..01890bb51 100644 --- a/internal/types/action/action_test.go +++ b/internal/types/action/action_test.go @@ -44,8 +44,8 @@ func TestAction(t *testing.T) { want: "*", }, { - action: Connect, - want: "connect", + action: Authorize, + want: "authorize", }, { action: AddGrants,