2021-02-23 19:06:39 -05:00
// Copyright (c) HashiCorp, Inc.
2022-07-19 15:16:24 -07:00
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2021-02-23 19:06:39 -05:00
package targetscmd
import (
2021-06-22 22:26:26 -04:00
"bytes"
"encoding/base64"
"encoding/json"
2021-02-23 19:06:39 -05:00
"fmt"
"strings"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"github.com/hashicorp/boundary/api/targets"
2021-05-04 19:57:35 -05:00
"github.com/hashicorp/boundary/globals"
2021-02-23 19:06:39 -05:00
"github.com/hashicorp/boundary/internal/cmd/base"
2021-06-25 14:06:31 -04:00
"github.com/hashicorp/boundary/internal/credential"
2023-11-02 16:03:47 -04:00
"github.com/hashicorp/boundary/internal/credential/static"
"github.com/hashicorp/boundary/internal/credential/vault"
2021-11-04 09:34:01 -04:00
"github.com/hashicorp/boundary/internal/types/scope"
2021-07-14 17:37:40 -07:00
"github.com/hashicorp/go-secure-stdlib/strutil"
2021-02-23 19:06:39 -05:00
"github.com/mitchellh/go-wordwrap"
"github.com/posener/complete"
)
func init () {
extraActionsFlagsMapFunc = extraActionsFlagsMapFuncImpl
extraSynopsisFunc = extraSynopsisFuncImpl
extraFlagsFunc = extraFlagsFuncImpl
extraFlagsHandlingFunc = extraFlagsHandlingFuncImpl
executeExtraActions = executeExtraActionsImpl
printCustomActionOutput = printCustomActionOutputImpl
}
type extraCmdVars struct {
2022-07-19 15:16:24 -07:00
flagHostSets [] string
flagHostSources [] string
flagBrokeredCredentialSources [] string
flagInjectedApplicationCredentialSources [] string
flagHostId string
sar * targets . SessionAuthorizationResult
2021-02-23 19:06:39 -05:00
}
func extraActionsFlagsMapFuncImpl () map [ string ][] string {
return map [ string ][] string {
2022-06-15 08:56:24 -07:00
"authorize-session" : { "id" , "host-id" },
"add-host-sources" : { "id" , "host-source" , "version" },
"remove-host-sources" : { "id" , "host-source" , "version" },
"set-host-sources" : { "id" , "host-source" , "version" },
2023-09-22 15:58:18 -04:00
"add-credential-sources" : { "id" , "brokered-credential-source" , "injected-application-credential-source" , "version" },
"remove-credential-sources" : { "id" , "brokered-credential-source" , "injected-application-credential-source" , "version" },
"set-credential-sources" : { "id" , "brokered-credential-source" , "injected-application-credential-source" , "version" },
2021-02-23 19:06:39 -05:00
}
}
func extraSynopsisFuncImpl ( c * Command ) string {
switch c . Func {
2021-07-30 08:48:03 -04:00
case "add-host-sources" , "set-host-sources" , "remove-host-sources" :
var in string
switch {
case strings . HasPrefix ( c . Func , "add" ):
in = "Add host sources to"
case strings . HasPrefix ( c . Func , "set" ):
in = "Set the full contents of the host sources on"
case strings . HasPrefix ( c . Func , "remove" ):
in = "Remove host sources from"
}
return wordwrap . WrapString ( fmt . Sprintf ( "%s a target" , in ), base . TermWidth )
2021-07-27 12:48:36 -04:00
case "add-credential-sources" , "set-credential-sources" , "remove-credential-sources" :
var in string
switch {
case strings . HasPrefix ( c . Func , "add" ):
in = "Add credential sources to"
case strings . HasPrefix ( c . Func , "set" ):
in = "Set the full contents of the credential sources on"
case strings . HasPrefix ( c . Func , "remove" ):
in = "Remove credential sources from"
}
2021-06-22 22:26:26 -04:00
return wordwrap . WrapString ( fmt . Sprintf ( "%s a target" , in ), base . TermWidth )
2021-02-23 19:06:39 -05:00
case "authorize-session" :
return "Request session authorization against the target"
default :
return ""
}
}
func ( c * Command ) extraHelpFunc ( helpMap map [ string ] func () string ) string {
var helpStr string
switch c . Func {
case "" :
return base . WrapForHelpText ([] string {
"Usage: boundary targets [sub command] [options] [args]" ,
"" ,
" This command allows operations on Boundary target resources. Example:" ,
"" ,
" Read a target:" ,
"" ,
` $ boundary targets read -id ttcp_1234567890` ,
"" ,
" Please see the targets subcommand help for detailed usage information." ,
})
case "create" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary targets create [type] [sub command] [options] [args]" ,
"" ,
" This command allows create operations on Boundary target resources. Example:" ,
"" ,
" Create a tcp-type target:" ,
"" ,
` $ boundary targets create tcp -name prodops -description "For ProdOps usage"` ,
"" ,
" Please see the typed subcommand help for detailed usage information." ,
})
case "update" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary targets update [type] [sub command] [options] [args]" ,
"" ,
" This command allows update operations on Boundary target resources. Example:" ,
"" ,
" Update a tcp-type target:" ,
"" ,
` $ boundary targets update tcp -id ttcp_1234567890 -name devops -description "For DevOps usage"` ,
"" ,
" Please see the typed subcommand help for detailed usage information." ,
})
2021-07-30 08:48:03 -04:00
case "add-host-sources" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target add-host-sources [options] [args]" ,
"" ,
" This command allows adding host sources to target resources. Example:" ,
"" ,
" Add host sources to a tcp-type target:" ,
"" ,
` $ boundary targets add-host-sources -id ttcp_1234567890 -host-source hsst_1234567890 -host-source hsst_0987654321` ,
"" ,
"" ,
})
case "remove-host-sources" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target remove-host-sources [options] [args]" ,
"" ,
" This command allows removing host sources from target resources. Example:" ,
"" ,
" Remove host sources from a tcp-type target:" ,
"" ,
` $ boundary targets remove-host-sources -id ttcp_1234567890 -host-source hsst_1234567890 -host-source hsst_0987654321` ,
"" ,
"" ,
})
case "set-host-sources" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target set-host-sources [options] [args]" ,
"" ,
" This command allows setting the complete set of host sources on a target resource. Example:" ,
"" ,
" Set host sources on a tcp-type target:" ,
"" ,
` $ boundary targets set-host-sources -id ttcp_1234567890 -host-source hsst_1234567890` ,
"" ,
"" ,
})
2021-07-27 12:48:36 -04:00
case "add-credential-sources" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target add-credential-sources [options] [args]" ,
"" ,
" This command allows adding credential sources to target resources. Example:" ,
"" ,
" Add credential sources to a tcp-type target:" ,
"" ,
2022-07-19 15:16:24 -07:00
` $ boundary targets add-credential-sources -id ttcp_1234567890 -brokered-credential-source clvlt_1234567890 -brokered-credential-source clvlt_0987654321` ,
2021-07-27 12:48:36 -04:00
"" ,
"" ,
})
case "remove-credential-sources" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target remove-credential-sources [options] [args]" ,
"" ,
" This command allows removing credential sources from target resources. Example:" ,
"" ,
" Remove credential sources from a tcp-type target:" ,
"" ,
2022-07-19 15:16:24 -07:00
` $ boundary targets remove-credential-sources -id ttcp_1234567890 -brokered-credential-source clvlt_1234567890 -brokered-credential-source clvlt_0987654321` ,
2021-07-27 12:48:36 -04:00
"" ,
"" ,
})
case "set-credential-sources" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target set-credential-sources [options] [args]" ,
"" ,
" This command allows setting the complete set of credential sources on a target resource. Example:" ,
"" ,
" Set credential sources on a tcp-type target:" ,
"" ,
2022-07-19 15:16:24 -07:00
` $ boundary targets set-credential-sources -id ttcp_1234567890 -brokered-credential-source clvlt_1234567890` ,
2021-07-27 12:48:36 -04:00
"" ,
"" ,
})
2021-02-23 19:06:39 -05:00
case "authorize-session" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary target authorize-session [options] [args]" ,
"" ,
" This command allows fetching session authorization credentials against a target. Example:" ,
"" ,
" Request an authorized session using the target ID:" ,
"" ,
` $ boundary targets authorize-session -id ttcp_1234567890` ,
"" ,
" Request an authorized session using the scope ID and target name:" ,
"" ,
` $ boundary targets authorize-session -scope-id o_1234567890 -name prod-ssh` ,
"" ,
"" ,
})
}
return helpStr + c . Flags (). Help ()
}
func extraFlagsFuncImpl ( c * Command , _ * base . FlagSets , f * base . FlagSet ) {
for _ , name := range flagsMap [ c . Func ] {
switch name {
case "host-set" :
f . StringSliceVar ( & base . StringSliceVar {
Name : "host-set" ,
Target : & c . flagHostSets ,
Usage : "The host-set resources to add, remove, or set. May be specified multiple times." ,
})
2021-07-30 08:48:03 -04:00
case "host-source" :
f . StringSliceVar ( & base . StringSliceVar {
Name : "host-source" ,
Target : & c . flagHostSources ,
Usage : "The host sources to add, remove, or set. May be specified multiple times." ,
})
2021-02-23 19:06:39 -05:00
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." ,
})
2022-07-19 15:16:24 -07:00
case "brokered-credential-source" :
f . StringSliceVar ( & base . StringSliceVar {
Name : "brokered-credential-source" ,
Target : & c . flagBrokeredCredentialSources ,
Usage : "The credential source to add, set, or remove that Boundary will return to the user when creating a connection. May be specified multiple times." ,
})
case "injected-application-credential-source" :
2021-10-28 14:25:57 -04:00
f . StringSliceVar ( & base . StringSliceVar {
2022-07-19 15:16:24 -07:00
Name : "injected-application-credential-source" ,
Target : & c . flagInjectedApplicationCredentialSources ,
Usage : "The credential source to add, set, or remove that Boundary will inject when creating a connection. May be specified multiple times." ,
2021-10-28 14:25:57 -04:00
})
2021-02-23 19:06:39 -05:00
}
}
if c . Func == "authorize-session" {
flagsMap [ c . Func ] = append ( flagsMap [ c . Func ], "name" , "scope-id" , "scope-name" )
// We put these here to change usage and change defaults (don't want
// them populated by default). Otherwise the common flags function will
// populate these values, and they can't be changed after-the-fact.
f . StringVar ( & base . StringVar {
Name : "name" ,
Target : & c . FlagName ,
Usage : "Target name, if authorizing the session via scope parameters and target name." ,
})
f . StringVar ( & base . StringVar {
Name : "scope-id" ,
Target : & c . FlagScopeId ,
EnvVar : "BOUNDARY_SCOPE_ID" ,
Completion : complete . PredictAnything ,
Usage : "Target scope ID, if authorizing the session via scope parameters and target name. Mutually exclusive with -scope-name." ,
})
f . StringVar ( & base . StringVar {
Name : "scope-name" ,
Target : & c . FlagScopeName ,
EnvVar : "BOUNDARY_SCOPE_NAME" ,
Completion : complete . PredictAnything ,
Usage : "Target scope name, if authorizing the session via scope parameters and target name. Mutually exclusive with -scope-id." ,
})
}
}
2021-04-08 20:54:32 -04:00
func extraFlagsHandlingFuncImpl ( c * Command , _ * base . FlagSets , opts * [] targets . Option ) bool {
2021-02-23 19:06:39 -05:00
// This is custom logic because of the authorized-session handling. If we
// support all resources to be looked up by name + scope info we can
// eventually graduate this out to the main template.
if strutil . StrListContains ( flagsMap [ c . Func ], "id" ) {
switch c . Func {
case "authorize-session" :
if c . FlagId == "" &&
( c . FlagName == "" ||
( c . FlagScopeId == "" && c . FlagScopeName == "" )) {
c . UI . Error ( "ID was not passed in, but no combination of name and scope ID/name was passed in either" )
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
if c . FlagId != "" &&
( c . FlagName != "" || c . FlagScopeId != "" || c . FlagScopeName != "" ) {
c . UI . Error ( "Cannot specify a target ID and also other lookup parameters" )
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
default :
if c . FlagId == "" {
c . UI . Error ( "ID is required but not passed in via -id" )
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
}
}
if strutil . StrListContains ( flagsMap [ c . Func ], "scope-id" ) && c . FlagScopeId != "" {
* opts = append ( * opts , targets . WithScopeId ( c . FlagScopeId ))
}
2024-09-13 15:09:38 -05:00
if strutil . StrListContains ( flagsMap [ c . Func ], "scope-name" ) && c . FlagScopeName != "" {
* opts = append ( * opts , targets . WithScopeName ( c . FlagScopeName ))
}
2021-02-23 19:06:39 -05:00
switch c . Func {
2021-07-30 08:48:03 -04:00
case "add-host-sources" , "remove-host-sources" :
if len ( c . flagHostSources ) == 0 {
c . UI . Error ( "No host sources supplied via -host-source" )
return false
}
case "set-host-sources" :
switch len ( c . flagHostSources ) {
case 0 :
c . UI . Error ( "No host sources supplied via -host-source" )
return false
case 1 :
if c . flagHostSources [ 0 ] == "null" {
c . flagHostSources = nil
}
}
2021-07-27 12:48:36 -04:00
case "add-credential-sources" , "remove-credential-sources" :
2022-07-19 15:16:24 -07:00
if len ( c . flagBrokeredCredentialSources ) + len ( c . flagInjectedApplicationCredentialSources ) == 0 {
c . UI . Error ( "No credential sources supplied via -brokered-credential-source or -injected-application-credential-source" )
2021-07-27 12:48:36 -04:00
return false
}
2021-10-28 14:25:57 -04:00
2022-07-19 15:16:24 -07:00
if len ( c . flagBrokeredCredentialSources ) > 0 {
* opts = append ( * opts , targets . WithBrokeredCredentialSourceIds ( c . flagBrokeredCredentialSources ))
2021-10-28 14:25:57 -04:00
}
2022-07-19 15:16:24 -07:00
if len ( c . flagInjectedApplicationCredentialSources ) > 0 {
* opts = append ( * opts , targets . WithInjectedApplicationCredentialSourceIds ( c . flagInjectedApplicationCredentialSources ))
2021-10-28 14:25:57 -04:00
}
2021-07-27 12:48:36 -04:00
case "set-credential-sources" :
2022-07-19 15:16:24 -07:00
if len ( c . flagBrokeredCredentialSources ) + len ( c . flagInjectedApplicationCredentialSources ) == 0 {
c . UI . Error ( "No credential sources supplied via -brokered-credential-source or -injected-application-credential-source" )
2021-10-28 14:25:57 -04:00
return false
}
2022-07-19 15:16:24 -07:00
switch len ( c . flagBrokeredCredentialSources ) {
2021-07-27 12:48:36 -04:00
case 0 :
2021-10-28 14:25:57 -04:00
// do nothing
2021-07-27 12:48:36 -04:00
case 1 :
2022-07-19 15:16:24 -07:00
if c . flagBrokeredCredentialSources [ 0 ] == "null" {
* opts = append ( * opts , targets . DefaultBrokeredCredentialSourceIds ())
2021-07-27 12:48:36 -04:00
break
}
fallthrough
default :
2022-07-19 15:16:24 -07:00
* opts = append ( * opts , targets . WithBrokeredCredentialSourceIds ( c . flagBrokeredCredentialSources ))
2021-07-27 12:48:36 -04:00
}
2022-07-19 15:16:24 -07:00
switch len ( c . flagInjectedApplicationCredentialSources ) {
2021-10-28 14:25:57 -04:00
case 0 :
// do nothing
case 1 :
2022-07-19 15:16:24 -07:00
if c . flagInjectedApplicationCredentialSources [ 0 ] == "null" {
* opts = append ( * opts , targets . DefaultInjectedApplicationCredentialSourceIds ())
2021-10-28 14:25:57 -04:00
break
}
fallthrough
default :
2022-07-19 15:16:24 -07:00
* opts = append ( * opts , targets . WithInjectedApplicationCredentialSourceIds ( c . flagInjectedApplicationCredentialSources ))
2021-10-28 14:25:57 -04:00
}
2021-07-27 12:48:36 -04:00
2021-02-23 19:06:39 -05:00
case "authorize-session" :
if len ( c . flagHostId ) != 0 {
* opts = append ( * opts , targets . WithHostId ( c . flagHostId ))
}
}
2021-03-04 20:05:17 -05:00
return true
2021-02-23 19:06:39 -05:00
}
2022-07-21 15:21:31 -07:00
func executeExtraActionsImpl ( c * Command , origResp * api . Response , origItem * targets . Target , origItems [] * targets . Target , origError error , targetClient * targets . Client , version uint32 , opts [] targets . Option ) ( * api . Response , * targets . Target , [] * targets . Target , error ) {
2021-02-23 19:06:39 -05:00
switch c . Func {
2021-07-30 08:48:03 -04:00
case "add-host-sources" :
2022-07-21 15:21:31 -07:00
result , err := targetClient . AddHostSources ( c . Context , c . FlagId , version , c . flagHostSources , opts ... )
2022-07-23 09:50:52 -07:00
if err != nil {
return nil , nil , nil , err
}
2022-07-21 15:21:31 -07:00
return result . GetResponse (), result . GetItem (), nil , err
2021-07-30 08:48:03 -04:00
case "remove-host-sources" :
2022-07-21 15:21:31 -07:00
result , err := targetClient . RemoveHostSources ( c . Context , c . FlagId , version , c . flagHostSources , opts ... )
2022-07-23 09:50:52 -07:00
if err != nil {
return nil , nil , nil , err
}
2022-07-21 15:21:31 -07:00
return result . GetResponse (), result . GetItem (), nil , err
2021-07-30 08:48:03 -04:00
case "set-host-sources" :
2022-07-21 15:21:31 -07:00
result , err := targetClient . SetHostSources ( c . Context , c . FlagId , version , c . flagHostSources , opts ... )
2022-07-23 09:50:52 -07:00
if err != nil {
return nil , nil , nil , err
}
2022-07-21 15:21:31 -07:00
return result . GetResponse (), result . GetItem (), nil , err
2021-07-27 12:48:36 -04:00
case "add-credential-sources" :
2022-07-21 15:21:31 -07:00
result , err := targetClient . AddCredentialSources ( c . Context , c . FlagId , version , opts ... )
2022-07-23 09:50:52 -07:00
if err != nil {
return nil , nil , nil , err
}
2022-07-21 15:21:31 -07:00
return result . GetResponse (), result . GetItem (), nil , err
2021-07-27 12:48:36 -04:00
case "remove-credential-sources" :
2022-07-21 15:21:31 -07:00
result , err := targetClient . RemoveCredentialSources ( c . Context , c . FlagId , version , opts ... )
2022-07-23 09:50:52 -07:00
if err != nil {
return nil , nil , nil , err
}
2022-07-21 15:21:31 -07:00
return result . GetResponse (), result . GetItem (), nil , err
2021-07-27 12:48:36 -04:00
case "set-credential-sources" :
2022-07-21 15:21:31 -07:00
result , err := targetClient . SetCredentialSources ( c . Context , c . FlagId , version , opts ... )
2022-07-23 09:50:52 -07:00
if err != nil {
return nil , nil , nil , err
}
2022-07-21 15:21:31 -07:00
return result . GetResponse (), result . GetItem (), nil , err
2021-02-23 19:06:39 -05:00
case "authorize-session" :
var err error
c . plural = "a session against target"
c . sar , err = targetClient . AuthorizeSession ( c . Context , c . FlagId , opts ... )
2022-07-21 15:21:31 -07:00
return nil , nil , nil , err
2021-02-23 19:06:39 -05:00
}
2022-07-21 15:21:31 -07:00
return origResp , origItem , origItems , origError
2021-02-23 19:06:39 -05:00
}
func ( c * Command ) printListTable ( items [] * targets . Target ) string {
if len ( items ) == 0 {
return "No targets found"
}
var output [] string
output = [] string {
"" ,
"Target information:" ,
}
2021-05-04 19:57:35 -05:00
for i , item := range items {
2021-02-23 19:06:39 -05:00
if i > 0 {
output = append ( output , "" )
}
2021-05-04 19:57:35 -05:00
if item . Id != "" {
2021-02-23 19:06:39 -05:00
output = append ( output ,
2021-05-04 19:57:35 -05:00
fmt . Sprintf ( " ID: %s" , item . Id ),
)
} else {
output = append ( output ,
fmt . Sprintf ( " ID: %s" , "(not available)" ),
)
}
if c . FlagRecursive && item . ScopeId != "" {
output = append ( output ,
fmt . Sprintf ( " Scope ID: %s" , item . ScopeId ),
2021-02-23 19:06:39 -05:00
)
}
2021-05-04 19:57:35 -05:00
if item . Version > 0 {
2021-02-23 19:06:39 -05:00
output = append ( output ,
2021-05-04 19:57:35 -05:00
fmt . Sprintf ( " Version: %d" , item . Version ),
2021-02-23 19:06:39 -05:00
)
}
2021-05-04 19:57:35 -05:00
if item . Type != "" {
2021-02-23 19:06:39 -05:00
output = append ( output ,
2021-05-04 19:57:35 -05:00
fmt . Sprintf ( " Type: %s" , item . Type ),
2021-02-23 19:06:39 -05:00
)
}
2021-05-04 19:57:35 -05:00
if item . Name != "" {
2021-02-23 19:06:39 -05:00
output = append ( output ,
2021-05-04 19:57:35 -05:00
fmt . Sprintf ( " Name: %s" , item . Name ),
2021-02-23 19:06:39 -05:00
)
}
2021-05-04 19:57:35 -05:00
if item . Description != "" {
2021-02-23 19:06:39 -05:00
output = append ( output ,
2021-05-04 19:57:35 -05:00
fmt . Sprintf ( " Description: %s" , item . Description ),
2021-02-23 19:06:39 -05:00
)
}
2022-11-11 13:48:18 +00:00
if item . Address != "" {
output = append ( output ,
fmt . Sprintf ( " Address: %s" , item . Address ),
)
}
2021-05-04 19:57:35 -05:00
if len ( item . AuthorizedActions ) > 0 {
2021-02-23 19:06:39 -05:00
output = append ( output ,
" Authorized Actions:" ,
2021-05-04 19:57:35 -05:00
base . WrapSlice ( 6 , item . AuthorizedActions ),
2021-02-23 19:06:39 -05:00
)
}
}
return base . WrapForHelpText ( output )
}
2022-07-21 15:21:31 -07:00
func printItemTable ( item * targets . Target , resp * api . Response ) string {
2022-10-25 18:29:38 -05:00
nonAttributeMap := map [ string ] any {}
2021-05-04 19:57:35 -05:00
if item . Id != "" {
nonAttributeMap [ "ID" ] = item . Id
}
if item . Version != 0 {
nonAttributeMap [ "Version" ] = item . Version
}
if item . Type != "" {
nonAttributeMap [ "Type" ] = item . Type
}
if ! item . CreatedTime . IsZero () {
nonAttributeMap [ "Created Time" ] = item . CreatedTime . Local (). Format ( time . RFC1123 )
}
if ! item . UpdatedTime . IsZero () {
nonAttributeMap [ "Updated Time" ] = item . UpdatedTime . Local (). Format ( time . RFC1123 )
2021-02-23 19:06:39 -05:00
}
if item . Name != "" {
nonAttributeMap [ "Name" ] = item . Name
}
if item . Description != "" {
nonAttributeMap [ "Description" ] = item . Description
}
2022-11-11 13:48:18 +00:00
if item . Address != "" {
nonAttributeMap [ "Address" ] = item . Address
}
2021-02-23 19:06:39 -05:00
if item . WorkerFilter != "" {
nonAttributeMap [ "Worker Filter" ] = item . WorkerFilter
}
2022-11-30 15:23:37 -05:00
if item . EgressWorkerFilter != "" {
nonAttributeMap [ "Egress Worker Filter" ] = item . EgressWorkerFilter
}
if item . IngressWorkerFilter != "" {
nonAttributeMap [ "Ingress Worker Filter" ] = item . IngressWorkerFilter
}
2022-07-21 15:21:31 -07:00
if resp != nil && resp . Map != nil {
if resp . Map [ globals . SessionConnectionLimitField ] != nil {
2021-05-04 19:57:35 -05:00
nonAttributeMap [ "Session Connection Limit" ] = item . SessionConnectionLimit
}
2022-07-21 15:21:31 -07:00
if resp . Map [ globals . SessionMaxSecondsField ] != nil {
2021-05-04 19:57:35 -05:00
nonAttributeMap [ "Session Max Seconds" ] = item . SessionMaxSeconds
}
}
2021-02-23 19:06:39 -05:00
maxLength := base . MaxAttributesLength ( nonAttributeMap , item . Attributes , keySubstMap )
2022-10-25 18:29:38 -05:00
var hostSourceMaps [] map [ string ] any
2022-09-15 09:20:08 -04:00
if len ( item . HostSources ) > 0 {
2021-07-30 08:48:03 -04:00
for _ , set := range item . HostSources {
2022-10-25 18:29:38 -05:00
m := map [ string ] any {
2021-07-30 08:48:03 -04:00
"ID" : set . Id ,
"Host Catalog ID" : set . HostCatalogId ,
}
hostSourceMaps = append ( hostSourceMaps , m )
}
if l := len ( "Host Catalog ID" ); l > maxLength {
maxLength = l
}
2021-02-23 19:06:39 -05:00
}
2022-10-25 18:29:38 -05:00
var credentialSourceMaps map [ credential . Purpose ][] map [ string ] any
2022-07-19 15:16:24 -07:00
if len ( item . BrokeredCredentialSources ) > 0 {
2021-07-27 12:48:36 -04:00
if credentialSourceMaps == nil {
2022-10-25 18:29:38 -05:00
credentialSourceMaps = make ( map [ credential . Purpose ][] map [ string ] any )
2021-06-25 14:06:31 -04:00
}
2022-10-25 18:29:38 -05:00
var brokeredCredentialSourceMaps [] map [ string ] any
2022-07-19 15:16:24 -07:00
for _ , source := range item . BrokeredCredentialSources {
2022-10-25 18:29:38 -05:00
m := map [ string ] any {
2022-06-10 12:26:19 -07:00
"ID" : source . Id ,
"Credential Store ID" : source . CredentialStoreId ,
2021-06-22 22:26:26 -04:00
}
2022-07-19 15:16:24 -07:00
brokeredCredentialSourceMaps = append ( brokeredCredentialSourceMaps , m )
2021-06-22 22:26:26 -04:00
}
2022-07-19 15:16:24 -07:00
credentialSourceMaps [ credential . BrokeredPurpose ] = brokeredCredentialSourceMaps
2021-06-22 22:26:26 -04:00
if l := len ( "Credential Store ID" ); l > maxLength {
maxLength = l
}
}
2022-07-19 15:16:24 -07:00
if len ( item . InjectedApplicationCredentialSources ) > 0 {
2022-06-10 12:26:19 -07:00
if credentialSourceMaps == nil {
2022-10-25 18:29:38 -05:00
credentialSourceMaps = make ( map [ credential . Purpose ][] map [ string ] any )
2022-06-10 12:26:19 -07:00
}
2022-10-25 18:29:38 -05:00
var injectedApplicationCredentialSourceMaps [] map [ string ] any
2022-07-19 15:16:24 -07:00
for _ , source := range item . InjectedApplicationCredentialSources {
2022-10-25 18:29:38 -05:00
m := map [ string ] any {
2022-06-10 12:26:19 -07:00
"ID" : source . Id ,
"Credential Store ID" : source . CredentialStoreId ,
}
2022-07-19 15:16:24 -07:00
injectedApplicationCredentialSourceMaps = append ( injectedApplicationCredentialSourceMaps , m )
2022-06-10 12:26:19 -07:00
}
2022-07-19 15:16:24 -07:00
credentialSourceMaps [ credential . InjectedApplicationPurpose ] = injectedApplicationCredentialSourceMaps
2022-06-10 12:26:19 -07:00
if l := len ( "Credential Store ID" ); l > maxLength {
maxLength = l
}
}
2021-06-22 22:26:26 -04:00
2024-02-14 13:14:56 -08:00
var aliasMaps [] map [ string ] any
if len ( item . Aliases ) > 0 {
for _ , al := range item . Aliases {
m := map [ string ] any {
"ID" : al . Id ,
"Value" : al . Value ,
}
aliasMaps = append ( aliasMaps , m )
}
if l := len ( "Value" ); l > maxLength {
maxLength = l
}
}
2021-02-23 19:06:39 -05:00
ret := [] string {
"" ,
"Target information:" ,
base . WrapMap ( 2 , maxLength + 2 , nonAttributeMap ),
2021-05-04 19:57:35 -05:00
}
if item . Scope != nil {
ret = append ( ret ,
"" ,
" Scope:" ,
base . ScopeInfoForOutput ( item . Scope , maxLength ),
)
2021-02-23 19:06:39 -05:00
}
if len ( item . AuthorizedActions ) > 0 {
ret = append ( ret ,
"" ,
" Authorized Actions:" ,
base . WrapSlice ( 4 , item . AuthorizedActions ),
)
}
ret = append ( ret ,
"" ,
)
2024-02-14 13:14:56 -08:00
if len ( aliasMaps ) > 0 {
ret = append ( ret ,
" Aliases:" ,
)
for _ , m := range aliasMaps {
ret = append ( ret ,
base . WrapMap ( 4 , maxLength , m ),
"" ,
)
}
}
2021-07-30 08:48:03 -04:00
if len ( hostSourceMaps ) > 0 {
2021-02-23 19:06:39 -05:00
ret = append ( ret ,
2021-07-30 08:48:03 -04:00
" Host Sources:" ,
2021-02-23 19:06:39 -05:00
)
2021-07-30 08:48:03 -04:00
for _ , m := range hostSourceMaps {
2021-02-23 19:06:39 -05:00
ret = append ( ret ,
base . WrapMap ( 4 , maxLength , m ),
"" ,
)
}
}
2022-06-10 12:26:19 -07:00
for purpose , sources := range credentialSourceMaps {
switch purpose {
2022-07-19 15:16:24 -07:00
case credential . BrokeredPurpose :
2021-06-22 22:26:26 -04:00
ret = append ( ret ,
2022-07-19 15:16:24 -07:00
" Brokered Credential Sources:" ,
2021-06-22 22:26:26 -04:00
)
2022-07-19 15:16:24 -07:00
case credential . InjectedApplicationPurpose :
2022-06-10 12:26:19 -07:00
ret = append ( ret ,
2022-07-19 15:16:24 -07:00
" Injected Application Credential Sources:" ,
2022-06-10 12:26:19 -07:00
)
}
for _ , m := range sources {
ret = append ( ret ,
base . WrapMap ( 4 , maxLength , m ),
"" ,
)
2021-06-22 22:26:26 -04:00
}
}
2021-02-23 19:06:39 -05:00
if len ( item . Attributes ) > 0 {
ret = append ( ret ,
" Attributes:" ,
base . WrapMap ( 4 , maxLength , item . Attributes ),
)
}
return base . WrapForHelpText ( ret )
}
func printCustomActionOutputImpl ( c * Command ) ( bool , error ) {
switch c . Func {
case "authorize-session" :
item := c . sar . GetItem ().( * targets . SessionAuthorization )
switch base . Format ( c . UI ) {
case "table" :
var ret [] string
2022-10-25 18:29:38 -05:00
nonAttributeMap := map [ string ] any {
2021-02-23 19:06:39 -05:00
"Session ID" : item . SessionId ,
"Target ID" : item . TargetId ,
"Scope ID" : item . Scope . Id ,
"User ID" : item . UserId ,
"Host ID" : item . HostId ,
"Endpoint" : item . Endpoint ,
"Created Time" : item . CreatedTime . Local (). Format ( time . RFC1123 ),
"Type" : item . Type ,
"Authorization Token" : item . AuthorizationToken ,
}
maxLength := 0
for k := range nonAttributeMap {
if len ( k ) > maxLength {
maxLength = len ( k )
}
}
ret = append ( ret , "" , "Target information:" )
ret = append ( ret ,
2021-06-22 22:26:26 -04:00
// We do +2 because there is another +2 offset for credentials below
2021-02-23 19:06:39 -05:00
base . WrapMap ( 2 , maxLength + 2 , nonAttributeMap ),
)
2021-06-22 22:26:26 -04:00
ret = append ( ret ,
"" ,
)
if len ( item . Credentials ) > 0 {
ret = append ( ret ,
" Credentials:" ,
)
for _ , cred := range item . Credentials {
2021-06-30 18:02:03 -04:00
if cred . Secret == nil || len ( cred . Secret . Raw ) == 0 {
2021-06-25 14:06:31 -04:00
continue
}
2021-06-22 22:26:26 -04:00
ret = append ( ret ,
2022-01-05 14:15:38 -08:00
fmt . Sprintf ( " Credential Store ID: %s" , cred . CredentialSource . CredentialStoreId ),
2021-07-27 12:48:36 -04:00
fmt . Sprintf ( " Credential Source ID: %s" , cred . CredentialSource . Id ),
fmt . Sprintf ( " Credential Source Type: %s" , cred . CredentialSource . Type ))
2021-06-22 22:26:26 -04:00
2021-07-27 12:48:36 -04:00
if len ( cred . CredentialSource . Name ) > 0 {
2021-06-22 22:26:26 -04:00
ret = append ( ret ,
2021-07-27 12:48:36 -04:00
fmt . Sprintf ( " Credential Source Name: %s" , cred . CredentialSource . Name ))
2021-06-22 22:26:26 -04:00
}
2021-07-27 12:48:36 -04:00
if len ( cred . CredentialSource . Description ) > 0 {
2021-06-22 22:26:26 -04:00
ret = append ( ret ,
2021-07-27 12:48:36 -04:00
fmt . Sprintf ( " Credential Source Description: %s" , cred . CredentialSource . Description ))
2021-06-22 22:26:26 -04:00
}
2022-01-05 14:15:38 -08:00
if cred . CredentialSource . CredentialType != "" {
ret = append ( ret ,
fmt . Sprintf ( " Credential Type: %s" , cred . CredentialSource . CredentialType ))
}
2021-06-25 14:06:31 -04:00
var secretStr [] string
2021-07-27 12:48:36 -04:00
switch cred . CredentialSource . Type {
2023-11-02 16:03:47 -04:00
case vault . Subtype . String (), vault . GenericLibrarySubtype . String (), static . Subtype . String ():
2022-01-05 14:15:38 -08:00
switch {
case cred . Credential != nil :
maxLength := 0
for k := range cred . Credential {
if len ( k ) > maxLength {
maxLength = len ( k )
}
}
secretStr = [] string { fmt . Sprintf ( " %s" , base . WrapMap ( 2 , maxLength + 2 , cred . Credential ))}
default :
// If it's Vault, the result will be JSON, except in
// specific circumstances that aren't used for
// credential fetching. So we can take the bytes
// as-is (after base64-decoding), but we'll format
// it nicely.
in , err := base64 . StdEncoding . DecodeString ( strings . Trim ( string ( cred . Secret . Raw ), `"` ))
if err != nil {
return false , fmt . Errorf ( "Error decoding secret as base64: %w" , err )
}
dst := new ( bytes . Buffer )
if err := json . Indent ( dst , in , " " , " " ); err != nil {
return false , fmt . Errorf ( "Error pretty-printing JSON: %w" , err )
}
secretStr = strings . Split ( dst . String (), "\n" )
if len ( secretStr ) > 0 {
// Indent doesn't apply to the first line 🙄
secretStr [ 0 ] = fmt . Sprintf ( " %s" , secretStr [ 0 ])
}
2021-06-25 14:06:31 -04:00
}
2021-06-22 22:26:26 -04:00
default :
// If it's not Vault, and not another known type,
// print out the base64-encoded value and leave it
// to the user to sort out.
2021-06-25 14:06:31 -04:00
secretStr = [] string { fmt . Sprintf ( " %s" , secretStr )}
2021-06-22 22:26:26 -04:00
}
2021-06-25 14:06:31 -04:00
ret = append ( ret , " Secret:" )
ret = append ( ret , secretStr ... )
ret = append ( ret , "" )
2021-06-22 22:26:26 -04:00
}
}
2021-02-23 19:06:39 -05:00
c . UI . Output ( base . WrapForHelpText ( ret ))
return true , nil
case "json" :
2022-07-21 15:21:31 -07:00
if ok := c . PrintJsonItem ( c . sar . GetResponse ()); ! ok {
2021-04-09 12:09:51 -05:00
return false , fmt . Errorf ( "Error formatting as JSON" )
2021-02-23 19:06:39 -05:00
}
return true , nil
}
}
return false , nil
}
var keySubstMap = map [ string ] string {
2023-05-04 13:01:38 -07:00
"default_port" : "Default Port" ,
"default_client_port" : "Default Client Port" ,
"enable_session_recording" : "Enable Session Recording" ,
"storage_bucket_id" : "Storage Bucket ID" ,
2021-02-23 19:06:39 -05:00
}
func exampleOutput () string {
2021-05-04 19:57:35 -05:00
item := & targets . Target {
2021-02-23 19:06:39 -05:00
Id : "ttcp_1234567890" ,
2021-11-04 09:34:01 -04:00
ScopeId : scope . Global . String (),
2021-02-23 19:06:39 -05:00
Scope : & scopes . ScopeInfo {
2021-11-04 09:34:01 -04:00
Id : scope . Global . String (),
2021-02-23 19:06:39 -05:00
},
2022-09-15 09:20:08 -04:00
Name : "foo" ,
Description : "The bar of foos" ,
CreatedTime : time . Now (). Add ( - 5 * time . Minute ),
UpdatedTime : time . Now (),
Version : 3 ,
Type : "tcp" ,
HostSourceIds : [] string { "hsst_1234567890" , "hsst_0987654321" },
HostSources : [] * targets . HostSource {
2021-02-23 19:06:39 -05:00
{
Id : "hsst_1234567890" ,
HostCatalogId : "hcst_1234567890" ,
},
{
Id : "hsst_0987654321" ,
HostCatalogId : "hcst_1234567890" ,
},
},
2022-07-19 15:16:24 -07:00
BrokeredCredentialSourceIds : [] string { "clvlt_1234567890" , "clvlt_0987654321" },
BrokeredCredentialSources : [] * targets . CredentialSource {
2021-06-22 22:26:26 -04:00
{
Id : "clvlt_1234567890" ,
CredentialStoreId : "csvlt_1234567890" ,
},
{
Id : "clvlt_098765421" ,
CredentialStoreId : "clvlt_0987654321" ,
},
},
2022-10-25 18:29:38 -05:00
Attributes : map [ string ] any {
2021-02-23 19:06:39 -05:00
"default_port" : 22 ,
},
}
2022-07-21 15:21:31 -07:00
return printItemTable ( item , nil )
2021-02-23 19:06:39 -05:00
}