Update target credential library service, API, SDK, CLI (#1343)
This commit is contained in:
1 parent
83c65d0d4b
commit
86c9a90554
27 files changed
+1474
-1127
No files matched your search
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/hashicorp/boundary/api/targets"
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
"github.com/hashicorp/boundary/internal/credential"
|
||||
"github.com/hashicorp/boundary/sdk/strutil"
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
"github.com/posener/complete"
|
||||
@@ -28,10 +29,10 @@ func init() {
|
||||
}
|
||||
|
||||
type extraCmdVars struct {
|
||||
flagHostSets []string
|
||||
flagCredentialLibraries []string
|
||||
flagHostId string
|
||||
sar *targets.SessionAuthorizationResult
|
||||
flagHostSets []string
|
||||
flagApplicationCredentialLibraries []string
|
||||
flagHostId string
|
||||
sar *targets.SessionAuthorizationResult
|
||||
}
|
||||
|
||||
func extraActionsFlagsMapFuncImpl() map[string][]string {
|
||||
@@ -40,9 +41,9 @@ func extraActionsFlagsMapFuncImpl() map[string][]string {
|
||||
"add-host-sets": {"id", "host-set", "version"},
|
||||
"remove-host-sets": {"id", "host-set", "version"},
|
||||
"set-host-sets": {"id", "host-set", "version"},
|
||||
"add-credential-libraries": {"id", "credential-library", "version"},
|
||||
"remove-credential-libraries": {"id", "credential-library", "version"},
|
||||
"set-credential-libraries": {"id", "credential-library", "version"},
|
||||
"add-credential-libraries": {"id", "application-credential-library", "version"},
|
||||
"remove-credential-libraries": {"id", "application-credential-library", "version"},
|
||||
"set-credential-libraries": {"id", "application-credential-library", "version"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +164,7 @@ func (c *Command) extraHelpFunc(helpMap map[string]func() string) string {
|
||||
"",
|
||||
" Add credential-library resources to a tcp-type target:",
|
||||
"",
|
||||
` $ boundary targets add-credential-libraries -id ttcp_1234567890 -credential-library clvlt_1234567890 -credential-library clvlt_0987654321`,
|
||||
` $ boundary targets add-credential-libraries -id ttcp_1234567890 -application-credential-library clvlt_1234567890 -application-credential-library clvlt_0987654321`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
@@ -175,7 +176,7 @@ func (c *Command) extraHelpFunc(helpMap map[string]func() string) string {
|
||||
"",
|
||||
" Remove credential-library resources from a tcp-type target:",
|
||||
"",
|
||||
` $ boundary targets remove-credential-libraries -id ttcp_1234567890 -credential-library clvlt_1234567890 -credential-library clvlt_0987654321`,
|
||||
` $ boundary targets remove-credential-libraries -id ttcp_1234567890 -application-credential-library clvlt_1234567890 -application-credential-library clvlt_0987654321`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
@@ -187,7 +188,7 @@ func (c *Command) extraHelpFunc(helpMap map[string]func() string) string {
|
||||
"",
|
||||
" Set credential-library resources on a tcp-type target:",
|
||||
"",
|
||||
` $ boundary targets set-credential-libraries -id ttcp_1234567890 -credential-library clvlt_1234567890`,
|
||||
` $ boundary targets set-credential-libraries -id ttcp_1234567890 -application-credential-library clvlt_1234567890`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
@@ -226,11 +227,11 @@ func extraFlagsFuncImpl(c *Command, _ *base.FlagSets, f *base.FlagSet) {
|
||||
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.",
|
||||
})
|
||||
case "credential-library":
|
||||
case "application-credential-library":
|
||||
f.StringSliceVar(&base.StringSliceVar{
|
||||
Name: "credential-library",
|
||||
Target: &c.flagCredentialLibraries,
|
||||
Usage: "The credential-library resource to add, remove, or set. May be specified multiple times.",
|
||||
Name: "application-credential-library",
|
||||
Target: &c.flagApplicationCredentialLibraries,
|
||||
Usage: "The credential-library resource for application purpose to add, set, or remove. May be specified multiple times.",
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -314,20 +315,27 @@ func extraFlagsHandlingFuncImpl(c *Command, _ *base.FlagSets, opts *[]targets.Op
|
||||
}
|
||||
|
||||
case "add-credential-libraries", "remove-credential-libraries":
|
||||
if len(c.flagCredentialLibraries) == 0 {
|
||||
c.UI.Error("No credential-library supplied via -credential-library")
|
||||
// TODO: As we add other purposes, add them to this check
|
||||
if len(c.flagApplicationCredentialLibraries) == 0 {
|
||||
c.UI.Error("No credential-libraries supplied via -application-credential-library")
|
||||
return false
|
||||
}
|
||||
*opts = append(*opts, targets.WithApplicationCredentialLibraryIds(c.flagApplicationCredentialLibraries))
|
||||
|
||||
case "set-credential-libraries":
|
||||
switch len(c.flagCredentialLibraries) {
|
||||
case 0:
|
||||
c.UI.Error("No credential-libraries supplied via -credential-library")
|
||||
// TODO: As we add other purposes, add them to this check
|
||||
if len(c.flagApplicationCredentialLibraries) == 0 {
|
||||
c.UI.Error("No credential-libraries supplied via -application-credential-library")
|
||||
return false
|
||||
}
|
||||
switch len(c.flagApplicationCredentialLibraries) {
|
||||
case 0:
|
||||
case 1:
|
||||
if c.flagCredentialLibraries[0] == "null" {
|
||||
c.flagCredentialLibraries = nil
|
||||
if c.flagApplicationCredentialLibraries[0] == "null" {
|
||||
*opts = append(*opts, targets.DefaultApplicationCredentialLibraryIds())
|
||||
}
|
||||
default:
|
||||
*opts = append(*opts, targets.WithApplicationCredentialLibraryIds(c.flagApplicationCredentialLibraries))
|
||||
}
|
||||
|
||||
case "authorize-session":
|
||||
@@ -348,11 +356,11 @@ func executeExtraActionsImpl(c *Command, origResult api.GenericResult, origError
|
||||
case "set-host-sets":
|
||||
return targetClient.SetHostSets(c.Context, c.FlagId, version, c.flagHostSets, opts...)
|
||||
case "add-credential-libraries":
|
||||
return targetClient.AddCredentialLibraries(c.Context, c.FlagId, version, c.flagCredentialLibraries, opts...)
|
||||
return targetClient.AddCredentialLibraries(c.Context, c.FlagId, version, opts...)
|
||||
case "remove-credential-libraries":
|
||||
return targetClient.RemoveCredentialLibraries(c.Context, c.FlagId, version, c.flagCredentialLibraries, opts...)
|
||||
return targetClient.RemoveCredentialLibraries(c.Context, c.FlagId, version, opts...)
|
||||
case "set-credential-libraries":
|
||||
return targetClient.SetCredentialLibraries(c.Context, c.FlagId, version, c.flagCredentialLibraries, opts...)
|
||||
return targetClient.SetCredentialLibraries(c.Context, c.FlagId, version, opts...)
|
||||
case "authorize-session":
|
||||
var err error
|
||||
c.plural = "a session against target"
|
||||
@@ -472,15 +480,20 @@ func printItemTable(result api.GenericResult) string {
|
||||
}
|
||||
}
|
||||
|
||||
var libraryMaps []map[string]interface{}
|
||||
if len(item.CredentialLibraries) > 0 {
|
||||
for _, lib := range item.CredentialLibraries {
|
||||
var libraryMaps map[credential.Purpose][]map[string]interface{}
|
||||
if len(item.ApplicationCredentialLibraries) > 0 {
|
||||
if libraryMaps == nil {
|
||||
libraryMaps = make(map[credential.Purpose][]map[string]interface{})
|
||||
}
|
||||
var applicationLibraryMaps []map[string]interface{}
|
||||
for _, lib := range item.ApplicationCredentialLibraries {
|
||||
m := map[string]interface{}{
|
||||
"ID": lib.Id,
|
||||
"Credential Store ID": lib.CredentialStoreId,
|
||||
}
|
||||
libraryMaps = append(libraryMaps, m)
|
||||
applicationLibraryMaps = append(applicationLibraryMaps, m)
|
||||
}
|
||||
libraryMaps[credential.ApplicationPurpose] = applicationLibraryMaps
|
||||
if l := len("Credential Store ID"); l > maxLength {
|
||||
maxLength = l
|
||||
}
|
||||
@@ -524,15 +537,17 @@ func printItemTable(result api.GenericResult) string {
|
||||
}
|
||||
}
|
||||
|
||||
if len(item.CredentialLibraries) > 0 {
|
||||
ret = append(ret,
|
||||
" Credential Libraries:",
|
||||
)
|
||||
for _, m := range libraryMaps {
|
||||
if len(libraryMaps) > 0 {
|
||||
if appMap := libraryMaps[credential.ApplicationPurpose]; len(appMap) > 0 {
|
||||
ret = append(ret,
|
||||
base.WrapMap(4, maxLength, m),
|
||||
"",
|
||||
" Application Credential Libraries:",
|
||||
)
|
||||
for _, m := range appMap {
|
||||
ret = append(ret,
|
||||
base.WrapMap(4, maxLength, m),
|
||||
"",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,6 +604,10 @@ func printCustomActionOutputImpl(c *Command) (bool, error) {
|
||||
)
|
||||
|
||||
for _, cred := range item.Credentials {
|
||||
if len(cred.Secret) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
ret = append(ret,
|
||||
fmt.Sprintf(" Credential Store ID: %s", cred.CredentialLibrary.CredentialStoreId),
|
||||
fmt.Sprintf(" Credential Library ID: %s", cred.CredentialLibrary.Id),
|
||||
@@ -602,7 +621,7 @@ func printCustomActionOutputImpl(c *Command) (bool, error) {
|
||||
ret = append(ret,
|
||||
fmt.Sprintf(" Credential Library Description: %s", cred.CredentialLibrary.Description))
|
||||
}
|
||||
var secretStr string
|
||||
var secretStr []string
|
||||
switch cred.CredentialLibrary.Type {
|
||||
case "vault":
|
||||
// If it's Vault, the result will be JSON, except in
|
||||
@@ -610,26 +629,28 @@ func printCustomActionOutputImpl(c *Command) (bool, error) {
|
||||
// credential fetching. So we can take the bytes
|
||||
// as-is (after base64-decoding), but we'll format
|
||||
// it nicely.
|
||||
in, err := base64.StdEncoding.DecodeString(cred.Secret)
|
||||
in, err := base64.StdEncoding.DecodeString(strings.Trim(string(cred.Secret), `"`))
|
||||
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 {
|
||||
if err := json.Indent(dst, in, " ", " "); err != nil {
|
||||
return false, fmt.Errorf("Error pretty-printing JSON: %w", err)
|
||||
}
|
||||
secretStr = dst.String()
|
||||
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])
|
||||
}
|
||||
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.
|
||||
secretStr = fmt.Sprintf(" %s", secretStr)
|
||||
secretStr = []string{fmt.Sprintf(" %s", secretStr)}
|
||||
}
|
||||
ret = append(ret,
|
||||
fmt.Sprintf(" Secret:"),
|
||||
fmt.Sprintf(" %s", secretStr),
|
||||
"",
|
||||
)
|
||||
ret = append(ret, " Secret:")
|
||||
ret = append(ret, secretStr...)
|
||||
ret = append(ret, "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,7 +658,33 @@ func printCustomActionOutputImpl(c *Command) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case "json":
|
||||
if ok := c.PrintJsonItem(c.sar); !ok {
|
||||
if len(item.Credentials) > 0 {
|
||||
for _, cred := range item.Credentials {
|
||||
if len(cred.Secret) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch cred.CredentialLibrary.Type {
|
||||
case "vault":
|
||||
// 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), `"`))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Error decoding secret as base64: %w", err)
|
||||
}
|
||||
// Now that it's decoded, pop it back in the same place
|
||||
// as marshaled JSON
|
||||
cred.Secret = in
|
||||
default:
|
||||
// If it's not Vault, and not another known type,
|
||||
// leave it alone.
|
||||
}
|
||||
}
|
||||
}
|
||||
if ok := c.PrintJsonItem(c.sar, base.WithDecodedCredentials(item.Credentials)); !ok {
|
||||
return false, fmt.Errorf("Error formatting as JSON")
|
||||
}
|
||||
return true, nil
|
||||
@@ -675,8 +722,8 @@ func exampleOutput() string {
|
||||
HostCatalogId: "hcst_1234567890",
|
||||
},
|
||||
},
|
||||
CredentialLibraryIds: []string{"clvlt_1234567890", "clvlt_0987654321"},
|
||||
CredentialLibraries: []*targets.CredentialLibrary{
|
||||
ApplicationCredentialLibraryIds: []string{"clvlt_1234567890", "clvlt_0987654321"},
|
||||
ApplicationCredentialLibraries: []*targets.CredentialLibrary{
|
||||
{
|
||||
Id: "clvlt_1234567890",
|
||||
CredentialStoreId: "csvlt_1234567890",
|
||||
|
||||
@@ -59,30 +59,30 @@ func (c *TcpCommand) extraTcpHelpFunc(helpMap map[string]func() string) string {
|
||||
}
|
||||
|
||||
func extraTcpFlagsFuncImpl(c *TcpCommand, set *base.FlagSets, f *base.FlagSet) {
|
||||
f = set.NewFlagSet("TCP Target Options")
|
||||
fs := set.NewFlagSet("TCP Target Options")
|
||||
|
||||
for _, name := range flagsTcpMap[c.Func] {
|
||||
switch name {
|
||||
case "default-port":
|
||||
f.StringVar(&base.StringVar{
|
||||
fs.StringVar(&base.StringVar{
|
||||
Name: "default-port",
|
||||
Target: &c.flagDefaultPort,
|
||||
Usage: "The default port to set on the target.",
|
||||
})
|
||||
case "session-max-seconds":
|
||||
f.StringVar(&base.StringVar{
|
||||
fs.StringVar(&base.StringVar{
|
||||
Name: "session-max-seconds",
|
||||
Target: &c.flagSessionMaxSeconds,
|
||||
Usage: `The maximum lifetime of the session, including all connections. Can be specified as an integer number of seconds or a duration string.`,
|
||||
})
|
||||
case "session-connection-limit":
|
||||
f.StringVar(&base.StringVar{
|
||||
fs.StringVar(&base.StringVar{
|
||||
Name: "session-connection-limit",
|
||||
Target: &c.flagSessionConnectionLimit,
|
||||
Usage: "The maximum number of connections allowed for a session. -1 means unlimited.",
|
||||
})
|
||||
case "worker-filter":
|
||||
f.StringVar(&base.StringVar{
|
||||
fs.StringVar(&base.StringVar{
|
||||
Name: "worker-filter",
|
||||
Target: &c.flagWorkerFilter,
|
||||
Usage: "A boolean expression to filter which workers can handle sessions for this target.",
|
||||
|
||||
Reference in new issue
Block a user