diff --git a/internal/cmd/commands/targetscmd/ssh_funcs.go b/internal/cmd/commands/targetscmd/ssh_funcs.go index 5e71569b0..0ea1ac254 100644 --- a/internal/cmd/commands/targetscmd/ssh_funcs.go +++ b/internal/cmd/commands/targetscmd/ssh_funcs.go @@ -25,7 +25,7 @@ func extraSshActionsFlagsMapFuncImpl() map[string][]string { "create": { "address", "default-port", "default-client-port", "session-max-seconds", "session-connection-limit", "egress-worker-filter", "ingress-worker-filter", "enable-session-recording", - "storage-bucket-id", + "storage-bucket-id", "with-alias-value", "with-alias-scope-id", "with-alias-authorize-session-host-id", }, "update": { "address", "default-port", "default-client-port", "session-max-seconds", "session-connection-limit", @@ -46,6 +46,9 @@ type extraSshCmdVars struct { flagAddress string flagStorageBucketId string flagEnableSessionRecording string + flagWithAliasValue string + flagWithAliasScopeId string + flagWithAliasHostId string } func (c *SshCommand) extraSshHelpFunc(helpMap map[string]func() string) string { @@ -141,6 +144,25 @@ func extraSshFlagsFuncImpl(c *SshCommand, set *base.FlagSets, f *base.FlagSet) { Target: &c.flagEnableSessionRecording, Usage: "A boolean indicating if session recording is enabled for this target.", }) + case "with-alias-value": + fs.StringVar(&base.StringVar{ + Name: "with-alias-value", + Target: &c.flagWithAliasValue, + Usage: "The value for an alias to be created for and at the same time as this target.", + }) + case "with-alias-scope-id": + fs.StringVar(&base.StringVar{ + Name: "with-alias-scope-id", + Target: &c.flagWithAliasScopeId, + Default: "global", + Usage: "The scope id for an alias to be created for and at the same time as this target.", + }) + case "with-alias-authorize-session-host-id": + fs.StringVar(&base.StringVar{ + Name: "with-alias-authorize-session-host-id", + Target: &c.flagWithAliasHostId, + Usage: "The authorize session host id flag used by an alias to be created for and at the same time as this target.", + }) } } } @@ -267,6 +289,55 @@ func extraSshFlagsHandlingFuncImpl(c *SshCommand, _ *base.FlagSets, opts *[]targ return false } + var aliasValue string + switch c.flagWithAliasValue { + case "": + case "null": + c.UI.Error("The with-alias-value flag cannot be set to null") + return false + default: + aliasValue = c.flagWithAliasValue + } + + var aliasScopeId string + switch c.flagWithAliasScopeId { + case "": + case "null": + c.UI.Error("The with-alias-scope-id flag cannot be set to null") + return false + default: + aliasScopeId = c.flagWithAliasScopeId + } + + var aliasHostId string + switch c.flagWithAliasHostId { + case "": + case "null": + c.UI.Error("The with-alias-authorize-session-host-id flag cannot be set to null") + return false + default: + aliasHostId = c.flagWithAliasHostId + } + + switch { + case aliasValue != "" && aliasScopeId == "": + c.UI.Error("The with-alias-value flag must be used with the with-alias-scope-id flag") + return false + case aliasValue != "" && aliasScopeId != "": + a := targets.Alias{ + Value: aliasValue, + ScopeId: aliasScopeId, + } + if aliasHostId != "" { + a.Attributes = &targets.TargetAliasAttributes{ + AuthorizeSessionArguments: &targets.AuthorizeSessionArguments{ + HostId: aliasHostId, + }, + } + } + *opts = append(*opts, targets.WithAliases([]targets.Alias{a})) + } + return true } diff --git a/internal/cmd/commands/targetscmd/tcp_funcs.go b/internal/cmd/commands/targetscmd/tcp_funcs.go index 28c13f4d2..d726374ea 100644 --- a/internal/cmd/commands/targetscmd/tcp_funcs.go +++ b/internal/cmd/commands/targetscmd/tcp_funcs.go @@ -21,8 +21,16 @@ func init() { func extraTcpActionsFlagsMapFuncImpl() map[string][]string { return map[string][]string{ - "create": {"address", "default-port", "default-client-port", "session-max-seconds", "session-connection-limit", "egress-worker-filter", "ingress-worker-filter"}, - "update": {"address", "default-port", "default-client-port", "session-max-seconds", "session-connection-limit", "worker-filter", "egress-worker-filter", "ingress-worker-filter"}, + "create": { + "address", "default-port", "default-client-port", "session-max-seconds", + "session-connection-limit", "egress-worker-filter", "ingress-worker-filter", + "with-alias-value", "with-alias-scope-id", "with-alias-authorize-session-host-id", + }, + "update": { + "address", "default-port", "default-client-port", "session-max-seconds", + "session-connection-limit", "worker-filter", "egress-worker-filter", + "ingress-worker-filter", + }, } } @@ -35,6 +43,9 @@ type extraTcpCmdVars struct { flagEgressWorkerFilter string flagIngressWorkerFilter string flagAddress string + flagWithAliasValue string + flagWithAliasScopeId string + flagWithAliasHostId string } func (c *TcpCommand) extraTcpHelpFunc(helpMap map[string]func() string) string { @@ -118,6 +129,25 @@ func extraTcpFlagsFuncImpl(c *TcpCommand, set *base.FlagSets, f *base.FlagSet) { Target: &c.flagIngressWorkerFilter, Usage: "A boolean expression to filter which ingress workers can handle sessions for this target.", }) + case "with-alias-value": + fs.StringVar(&base.StringVar{ + Name: "with-alias-value", + Target: &c.flagWithAliasValue, + Usage: "The value for an alias to be created for and at the same time as this target.", + }) + case "with-alias-scope-id": + fs.StringVar(&base.StringVar{ + Name: "with-alias-scope-id", + Target: &c.flagWithAliasScopeId, + Default: "global", + Usage: "The scope id for an alias to be created for and at the same time as this target.", + }) + case "with-alias-authorize-session-host-id": + fs.StringVar(&base.StringVar{ + Name: "with-alias-authorize-session-host-id", + Target: &c.flagWithAliasHostId, + Usage: "The authorize session host id flag used by an alias to be created for and at the same time as this target.", + }) } } } @@ -225,5 +255,54 @@ func extraTcpFlagsHandlingFuncImpl(c *TcpCommand, _ *base.FlagSets, opts *[]targ *opts = append(*opts, targets.WithAddress(c.flagAddress)) } + var aliasValue string + switch c.flagWithAliasValue { + case "": + case "null": + c.UI.Error("The with-alias-value flag cannot be set to null") + return false + default: + aliasValue = c.flagWithAliasValue + } + + var aliasScopeId string + switch c.flagWithAliasScopeId { + case "": + case "null": + c.UI.Error("The with-alias-scope-id flag cannot be set to null") + return false + default: + aliasScopeId = c.flagWithAliasScopeId + } + + var aliasHostId string + switch c.flagWithAliasHostId { + case "": + case "null": + c.UI.Error("The with-alias-authorize-session-host-id flag cannot be set to null") + return false + default: + aliasHostId = c.flagWithAliasHostId + } + + switch { + case aliasValue != "" && aliasScopeId == "": + c.UI.Error("The with-alias-value flag must be used with the with-alias-scope-id flag") + return false + case aliasValue != "" && aliasScopeId != "": + a := targets.Alias{ + Value: aliasValue, + ScopeId: aliasScopeId, + } + if aliasHostId != "" { + a.Attributes = &targets.TargetAliasAttributes{ + AuthorizeSessionArguments: &targets.AuthorizeSessionArguments{ + HostId: aliasHostId, + }, + } + } + *opts = append(*opts, targets.WithAliases([]targets.Alias{a})) + } + return true } diff --git a/internal/tests/cli/boundary/_targets_alias.bash b/internal/tests/cli/boundary/_targets_alias.bash index 7d757d3e5..a77a28a56 100644 --- a/internal/tests/cli/boundary/_targets_alias.bash +++ b/internal/tests/cli/boundary/_targets_alias.bash @@ -3,6 +3,20 @@ load _authorized_actions +function create_tcp_target_with_alias() { + local sid=$1 + local port=$2 + local name=$3 + local alias=$4 + boundary targets create tcp \ + -address localhost \ + -default-port $port \ + -name $name \ + -scope-id $sid \ + -with-alias-value $alias \ + -format json +} + function read_target_by_alias() { boundary targets read $1 -format json } diff --git a/internal/tests/cli/boundary/target_aliases.bats b/internal/tests/cli/boundary/target_aliases.bats index 8e2020979..c2a152c63 100644 --- a/internal/tests/cli/boundary/target_aliases.bats +++ b/internal/tests/cli/boundary/target_aliases.bats @@ -103,8 +103,37 @@ export ALIAS_TGT_NAME='test-alias-target' [ "$status" -eq 0 ] } -@test "boundary/target: default user can delete target" { +@test "boundary/target: default user can delete target using alias" { run delete_target_by_alias $ALIAS_VALUE run has_status_code "$output" "204" [ "$status" -eq 0 ] +} + +@test "boundary/alias: default user can delete the alias" { + local aid=$(alias_id_from_target_alias $ALIAS_VALUE) + run delete_alias $aid + run has_status_code "$output" "204" + [ "$status" -eq 0 ] +} + +@test "boundary/target: default user can create target using alias" { + run create_tcp_target_with_alias $DEFAULT_P_ID 22 $ALIAS_TGT_NAME $ALIAS_VALUE + [ "$status" -eq 0 ] +} + +@test "boundary/target: default user can read target using alias" { + run read_target_by_alias $ALIAS_VALUE + [ "$status" -eq 0 ] +} + +@test "boundary/target: default user can delete target using created at the same time alias" { + run delete_target_by_alias $ALIAS_VALUE + [ "$status" -eq 0 ] +} + +@test "boundary/alias: default user can delete the created at the same time alias" { + local aid=$(alias_id_from_target_alias $ALIAS_VALUE) + run delete_alias $aid + run has_status_code "$output" "204" + [ "$status" -eq 0 ] } \ No newline at end of file