Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions cmd/config/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,34 @@ func TestConfigGetCmd_NoKey(t *testing.T) {
err := testutils_cobra.ExecutePingcli(t, "config", "get")
testutils.CheckExpectedError(t, err, &expectedErrorPattern)
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_getEmptyMaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "get", options.RequestAccessTokenOption.ViperKey)

// Output:
// Configuration values for profile 'default' and key 'request.accessToken':
// request.accessToken=
// request.accessTokenExpiry=0
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_getMaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "get", options.PingFederateClientCredentialsAuthClientSecretOption.ViperKey)

// Output:
// Configuration values for profile 'default' and key 'service.pingfederate.authentication.clientCredentialsAuth.clientSecret':
// service.pingfederate.authentication.clientCredentialsAuth.clientSecret=********
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_getUnmaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "get", options.RootColorOption.ViperKey)

// Output:
// Configuration values for profile 'default' and key 'noColor':
// noColor=true
}
20 changes: 20 additions & 0 deletions cmd/config/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,23 @@ func TestConfigSetCmd_InvalidFlag(t *testing.T) {
err := testutils_cobra.ExecutePingcli(t, "config", "set", "--invalid")
testutils.CheckExpectedError(t, err, &expectedErrorPattern)
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_setMaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "set", fmt.Sprintf("%s=%s", options.PingFederateBasicAuthPasswordOption.ViperKey, "1234"))

// Output:
// SUCCESS: Configuration set successfully:
// service.pingfederate.authentication.basicAuth.password=********
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_setUnmaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "set", fmt.Sprintf("%s=%s", options.RootColorOption.ViperKey, "true"))

// Output:
// SUCCESS: Configuration set successfully:
// noColor=true
}
20 changes: 20 additions & 0 deletions cmd/config/unset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,23 @@ func TestConfigUnsetCmd_HelpFlag(t *testing.T) {
err = testutils_cobra.ExecutePingcli(t, "config", "unset", "-h")
testutils.CheckExpectedError(t, err, nil)
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_unsetMaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "unset", options.PingFederateBasicAuthUsernameOption.ViperKey)

// Output:
// SUCCESS: Configuration unset successfully:
// service.pingfederate.authentication.basicAuth.username=
}

// https://pkg.go.dev/testing#hdr-Examples
func Example_unsetUnmaskedValue() {
t := testing.T{}
_ = testutils_cobra.ExecutePingcli(&t, "config", "unset", options.RootOutputFormatOption.ViperKey)

// Output:
// SUCCESS: Configuration unset successfully:
// outputFormat=text
}
27 changes: 21 additions & 6 deletions internal/commands/config/get_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config_internal

import (
"fmt"
"strings"

"github.com/pingidentity/pingcli/internal/configuration"
"github.com/pingidentity/pingcli/internal/configuration/options"
Expand All @@ -19,12 +20,26 @@ func RunInternalConfigGet(viperKey string) (err error) {
return fmt.Errorf("failed to get configuration: %v", err)
}

yamlStr, err := profiles.GetMainConfig().ProfileViperValue(pName, viperKey)
if err != nil {
return fmt.Errorf("failed to get configuration: %v", err)
msgStr := fmt.Sprintf("Configuration values for profile '%s' and key '%s':\n", pName, viperKey)

for _, opt := range options.Options() {
if opt.ViperKey == "" || !strings.Contains(opt.ViperKey, viperKey) {
continue
}

vVal, _, err := profiles.ViperValueFromOption(opt)
if err != nil {
return fmt.Errorf("failed to get configuration: %v", err)
}

if opt.Sensitive {
msgStr += fmt.Sprintf("%s=%s\n", opt.ViperKey, profiles.MaskValue(vVal))
} else {
msgStr += fmt.Sprintf("%s=%s\n", opt.ViperKey, vVal)
}
}

output.Message(yamlStr, nil)
output.Message(msgStr, nil)

return nil
}
Expand All @@ -37,11 +52,11 @@ func readConfigGetOptions() (pName string, err error) {
}

if err != nil {
return pName, err
return "", err
}

if pName == "" {
return pName, fmt.Errorf("unable to determine profile to get configuration from")
return "", fmt.Errorf("unable to determine profile to get configuration from")
}

return pName, nil
Expand Down
12 changes: 10 additions & 2 deletions internal/commands/config/set_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,20 @@ func RunInternalConfigSet(kvPair string) (err error) {
return fmt.Errorf("failed to set configuration: %v", err)
}

yamlStr, err := profiles.GetMainConfig().ProfileToString(pName)
msgStr := "Configuration set successfully:\n"

vVal, _, err := profiles.ViperValueFromOption(opt)
if err != nil {
return fmt.Errorf("failed to set configuration: %v", err)
}

output.Success("Configuration set successfully", map[string]interface{}{"Profile YAML": yamlStr})
if opt.Sensitive {
msgStr += fmt.Sprintf("%s=%s", vKey, profiles.MaskValue(vVal))
} else {
msgStr += fmt.Sprintf("%s=%s", vKey, vVal)
}

output.Success(msgStr, nil)

return nil
}
Expand Down
14 changes: 11 additions & 3 deletions internal/commands/config/unset_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@ func RunInternalConfigUnset(viperKey string) (err error) {
return fmt.Errorf("failed to unset configuration: %v", err)
}

yamlStr, err := profiles.GetMainConfig().ProfileToString(pName)
msgStr := "Configuration unset successfully:\n"

vVal, _, err := profiles.ViperValueFromOption(opt)
if err != nil {
return fmt.Errorf("failed to unset configuration: %v", err)
return fmt.Errorf("failed to set configuration: %v", err)
}

if opt.Sensitive {
msgStr += fmt.Sprintf("%s=%s", viperKey, profiles.MaskValue(vVal))
} else {
msgStr += fmt.Sprintf("%s=%s", viperKey, vVal)
}

output.Success("Configuration unset successfully", map[string]interface{}{"Profile YAML": yamlStr})
output.Success(msgStr, nil)

return nil
}
Expand Down
24 changes: 21 additions & 3 deletions internal/commands/config/view_profile_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,32 @@ func RunInternalConfigViewProfile(args []string) (err error) {
}
}

profileStr, err := profiles.GetMainConfig().ProfileToString(pName)
// Validate the profile name
err = profiles.GetMainConfig().ValidateExistingProfileName(pName)
if err != nil {
return fmt.Errorf("failed to view profile: %v", err)
}

profileStr = fmt.Sprintf("Profile: %s\n\n%s", pName, profileStr)
msgStr := fmt.Sprintf("Configuration for profile '%s':\n", pName)

output.Message(profileStr, nil)
for _, opt := range options.Options() {
if opt.ViperKey == "" {
continue
}

vVal, _, err := profiles.ViperValueFromOption(opt)
if err != nil {
return fmt.Errorf("failed to view profile: %v", err)
}

if opt.Sensitive {
msgStr += fmt.Sprintf("%s=%s\n", opt.ViperKey, profiles.MaskValue(vVal))
} else {
msgStr += fmt.Sprintf("%s=%s\n", opt.ViperKey, vVal)
}
}

output.Message(msgStr, nil)

return nil
}
15 changes: 2 additions & 13 deletions internal/commands/platform/export_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,19 +335,8 @@ func initPingOneApiClient(ctx context.Context, pingcliVersion string) (err error

pingoneApiClient, err = apiConfig.APIClient(ctx)
if err != nil {
return fmt.Errorf(`failed to initialize pingone API client.
%v

configuration values used for client initialization:
worker client ID - %s
worker client secret - %s
worker environment ID - %s
pingone region - %s`,
err,
pingoneApiClientId,
strings.Repeat("*", len(clientSecret)),
environmentID,
regionCode)
return fmt.Errorf("failed to initialize pingone API client. Check worker client ID, worker client secret,"+
" worker environment ID, and pingone region code configuration values. %v", err)
}

return nil
Expand Down
15 changes: 9 additions & 6 deletions internal/configuration/config/add_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ func initAddProfileDescriptionOption() {
Usage: "The description of the new configuration profile.",
Value: cobraValue,
},
Type: options.ENUM_STRING,
ViperKey: "", // No viper key
Sensitive: false,
Type: options.ENUM_STRING,
ViperKey: "", // No viper key
}
}

Expand All @@ -49,8 +50,9 @@ func initAddProfileNameOption() {
Usage: "The name of the new configuration profile.",
Value: cobraValue,
},
Type: options.ENUM_STRING,
ViperKey: "", // No viper key
Sensitive: false,
Type: options.ENUM_STRING,
ViperKey: "", // No viper key
}
}

Expand All @@ -72,7 +74,8 @@ func initAddProfileSetActiveOption() {
Value: cobraValue,
NoOptDefVal: "true", // Make this flag a boolean flag
},
Type: options.ENUM_BOOL,
ViperKey: "", // No viper key
Sensitive: false,
Type: options.ENUM_BOOL,
ViperKey: "", // No viper key
}
}
5 changes: 3 additions & 2 deletions internal/configuration/config/delete_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func initDeleteAutoAcceptOption() {
Value: cobraValue,
NoOptDefVal: "true", // Make the flag a boolean flag
},
Type: options.ENUM_STRING,
ViperKey: "", // No viper key
Sensitive: false,
Type: options.ENUM_STRING,
ViperKey: "", // No viper key
}
}
17 changes: 15 additions & 2 deletions internal/configuration/options/options.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package options

import "github.com/spf13/pflag"
import (
"slices"
"strings"

"github.com/spf13/pflag"
)

type OptionType string

Expand All @@ -27,12 +32,13 @@ type Option struct {
DefaultValue pflag.Value
EnvVar string
Flag *pflag.Flag
Sensitive bool
Type OptionType
ViperKey string
}

func Options() []Option {
return []Option{
optList := []Option{
PingOneAuthenticationTypeOption,
PingOneAuthenticationWorkerClientIDOption,
PingOneAuthenticationWorkerClientSecretOption,
Expand Down Expand Up @@ -79,6 +85,13 @@ func Options() []Option {
RequestAccessTokenExpiryOption,
RequestFailOption,
}

// Sort the options list by viper key
slices.SortFunc(optList, func(opt1, opt2 Option) int {
return strings.Compare(opt1.ViperKey, opt2.ViperKey)
})

return optList
}

// pingone service options
Expand Down
25 changes: 15 additions & 10 deletions internal/configuration/platform/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ func initFormatOption() {
),
Value: cobraValue,
},
Type: options.ENUM_STRING,
ViperKey: "export.format",
Sensitive: false,
Type: options.ENUM_STRING,
ViperKey: "export.format",
}
}

Expand Down Expand Up @@ -71,8 +72,9 @@ func initServicesOption() {
),
Value: cobraValue,
},
Type: options.ENUM_EXPORT_SERVICES,
ViperKey: "export.services",
Sensitive: false,
Type: options.ENUM_EXPORT_SERVICES,
ViperKey: "export.services",
}
}

Expand All @@ -96,8 +98,9 @@ func initOutputDirectoryOption() {
"\nExample: 'pingcli-export'",
Value: cobraValue,
},
Type: options.ENUM_STRING,
ViperKey: "export.outputDirectory",
Sensitive: false,
Type: options.ENUM_STRING,
ViperKey: "export.outputDirectory",
}
}

Expand All @@ -119,8 +122,9 @@ func initOverwriteOption() {
Value: cobraValue,
NoOptDefVal: "true", // Make this flag a boolean flag
},
Type: options.ENUM_BOOL,
ViperKey: "export.overwrite",
Sensitive: false,
Type: options.ENUM_BOOL,
ViperKey: "export.overwrite",
}
}

Expand All @@ -140,7 +144,8 @@ func initPingOneEnvironmentIDOption() {
Usage: "The ID of the PingOne environment to export. Must be a valid PingOne UUID.",
Value: cobraValue,
},
Type: options.ENUM_UUID,
ViperKey: "export.pingone.environmentID",
Sensitive: false,
Type: options.ENUM_UUID,
ViperKey: "export.pingone.environmentID",
}
}
1 change: 1 addition & 0 deletions internal/configuration/profiles/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func initDescriptionOption() {
DefaultValue: new(customtypes.String),
EnvVar: "", // No environment variable
Flag: nil, // No flag
Sensitive: false,
Type: options.ENUM_STRING,
ViperKey: "description",
}
Expand Down
Loading
Loading