diff --git a/.github/workflows/code-analysis-lint-test.yaml b/.github/workflows/code-analysis-lint-test.yaml index d21d3af6..85e4649e 100644 --- a/.github/workflows/code-analysis-lint-test.yaml +++ b/.github/workflows/code-analysis-lint-test.yaml @@ -124,6 +124,8 @@ jobs: runs-on: ubuntu-latest env: PING_IDENTITY_CONFIG: ${{ secrets.PING_IDENTITY_CONFIG }} + PINGCLI_PINGONE_AUTH_SERVICE_HOSTNAME: ${{ vars.PINGCLI_PINGONE_AUTH_SERVICE_HOSTNAME }} + PINGCLI_PINGONE_API_SERVICE_HOSTNAME: ${{ vars.PINGCLI_PINGONE_API_SERVICE_HOSTNAME }} PINGCLI_PINGONE_WORKER_CLIENT_ID: ${{ secrets.PINGCLI_PINGONE_WORKER_CLIENT_ID }} PINGCLI_PINGONE_WORKER_CLIENT_SECRET: ${{ secrets.PINGCLI_PINGONE_WORKER_CLIENT_SECRET }} PINGCLI_PINGONE_REGION_CODE: ${{ secrets.PINGCLI_PINGONE_REGION_CODE }} diff --git a/cmd/platform/export.go b/cmd/platform/export.go index 8b58271d..2674b986 100644 --- a/cmd/platform/export.go +++ b/cmd/platform/export.go @@ -99,6 +99,8 @@ func initPingOneExportFlags(cmd *cobra.Command) { cmd.Flags().AddFlag(options.PingOneAuthenticationWorkerEnvironmentIDOption.Flag) cmd.Flags().AddFlag(options.PingOneAuthenticationWorkerClientIDOption.Flag) cmd.Flags().AddFlag(options.PingOneAuthenticationWorkerClientSecretOption.Flag) + cmd.Flags().AddFlag(options.PingOneAuthenticationServiceHostnameOption.Flag) + cmd.Flags().AddFlag(options.PingOneAPIServiceHostnameOption.Flag) cmd.Flags().AddFlag(options.PingOneAuthenticationTypeOption.Flag) cmd.Flags().AddFlag(options.PingOneRegionCodeOption.Flag) @@ -109,6 +111,11 @@ func initPingOneExportFlags(cmd *cobra.Command) { options.PingOneRegionCodeOption.CobraParamName, ) + cmd.MarkFlagsRequiredTogether( + options.PingOneAuthenticationServiceHostnameOption.CobraParamName, + options.PingOneAPIServiceHostnameOption.CobraParamName, + ) + } func initPingFederateGeneralFlags(cmd *cobra.Command) { diff --git a/docs/tool-configuration/configuration-key.md b/docs/tool-configuration/configuration-key.md index 50011f67..ca7139ca 100644 --- a/docs/tool-configuration/configuration-key.md +++ b/docs/tool-configuration/configuration-key.md @@ -28,6 +28,8 @@ The following parameters can be configured in Ping CLI's static configuration fi | service.pingfederate.httpsHost | ENUM_STRING | --pingfederate-https-host | The PingFederate HTTPS host used to communicate with PingFederate's admin API.

Example: `https://pingfederate-admin.bxretail.org` | | service.pingfederate.insecureTrustAllTLS | ENUM_BOOL | --pingfederate-insecure-trust-all-tls | Trust any certificate when connecting to the PingFederate server admin API.

This is insecure and should not be enabled outside of testing. | | service.pingfederate.xBypassExternalValidationHeader | ENUM_BOOL | --pingfederate-x-bypass-external-validation-header | Bypass connection tests when configuring PingFederate (the X-BypassExternalValidation header when using PingFederate's admin API). | +| service.pingone.api.hostname | ENUM_STRING | --pingone-api-service-hostname | Override the service hostname for the PingOne management API. | +| service.pingone.authentication.hostname | ENUM_STRING | --pingone-auth-service-hostname | Override the service hostname used to authenticate to the PingOne management API. | | service.pingone.authentication.type | ENUM_PINGONE_AUTH_TYPE | --pingone-authentication-type | The authentication type to use to authenticate to the PingOne management API.

Options are: worker.

Example: `worker` | | service.pingone.authentication.worker.clientID | ENUM_UUID | --pingone-worker-client-id | The worker client ID used to authenticate to the PingOne management API. | | service.pingone.authentication.worker.clientSecret | ENUM_STRING | --pingone-worker-client-secret | The worker client secret used to authenticate to the PingOne management API. | diff --git a/internal/commands/platform/export_internal.go b/internal/commands/platform/export_internal.go index d1d692c3..dde4586e 100644 --- a/internal/commands/platform/export_internal.go +++ b/internal/commands/platform/export_internal.go @@ -313,6 +313,14 @@ func initPingOneApiClient(ctx context.Context, pingcliVersion string) (err error if err != nil { return err } + authServiceHostname, err := profiles.GetOptionValue(options.PingOneAuthenticationServiceHostnameOption) + if err != nil { + return err + } + apiServiceHostname, err := profiles.GetOptionValue(options.PingOneAPIServiceHostnameOption) + if err != nil { + return err + } regionCode, err := profiles.GetOptionValue(options.PingOneRegionCodeOption) if err != nil { return err @@ -340,6 +348,14 @@ func initPingOneApiClient(ctx context.Context, pingcliVersion string) (err error UserAgentSuffix: &userAgent, } + if authServiceHostname != "" { + apiConfig.AuthHostnameOverride = &authServiceHostname + } + + if apiServiceHostname != "" { + apiConfig.APIHostnameOverride = &apiServiceHostname + } + pingoneApiClient, err = apiConfig.APIClient(ctx) if err != nil { return fmt.Errorf("failed to initialize pingone API client. Check worker client ID, worker client secret,"+ diff --git a/internal/configuration/options/options.go b/internal/configuration/options/options.go index 52e0781d..ade2ef54 100644 --- a/internal/configuration/options/options.go +++ b/internal/configuration/options/options.go @@ -43,6 +43,8 @@ func Options() []Option { PingOneAuthenticationWorkerClientIDOption, PingOneAuthenticationWorkerClientSecretOption, PingOneAuthenticationWorkerEnvironmentIDOption, + PingOneAuthenticationServiceHostnameOption, + PingOneAPIServiceHostnameOption, PingOneRegionCodeOption, PlatformExportExportFormatOption, @@ -102,6 +104,8 @@ var ( PingOneAuthenticationTypeOption Option PingOneAuthenticationWorkerClientIDOption Option PingOneAuthenticationWorkerClientSecretOption Option + PingOneAuthenticationServiceHostnameOption Option + PingOneAPIServiceHostnameOption Option PingOneAuthenticationWorkerEnvironmentIDOption Option PingOneRegionCodeOption Option ) diff --git a/internal/configuration/services/pingone.go b/internal/configuration/services/pingone.go index eca3d5d3..a44d26f9 100644 --- a/internal/configuration/services/pingone.go +++ b/internal/configuration/services/pingone.go @@ -14,6 +14,8 @@ func InitPingOneServiceOptions() { initAuthenticationWorkerClientIDOption() initAuthenticationWorkerClientSecretOption() initAuthenticationWorkerEnvironmentIDOption() + initAuthenticationServiceHostnameOption() + initAPIServiceHostnameOption() initRegionCodeOption() } @@ -85,6 +87,48 @@ func initAuthenticationWorkerEnvironmentIDOption() { } } +func initAuthenticationServiceHostnameOption() { + cobraParamName := "pingone-auth-service-hostname" + cobraValue := new(customtypes.String) + defaultValue := customtypes.String("") + envVar := "PINGCLI_PINGONE_AUTH_SERVICE_HOSTNAME" + + options.PingOneAuthenticationServiceHostnameOption = options.Option{ + CobraParamName: cobraParamName, + CobraParamValue: cobraValue, + DefaultValue: &defaultValue, + EnvVar: envVar, + Flag: &pflag.Flag{ + Name: cobraParamName, + Usage: "Override the service hostname used to authenticate to the PingOne management API.", + Value: cobraValue, + }, + Type: options.ENUM_STRING, + ViperKey: "service.pingone.authentication.hostname", + } +} + +func initAPIServiceHostnameOption() { + cobraParamName := "pingone-api-service-hostname" + cobraValue := new(customtypes.String) + defaultValue := customtypes.String("") + envVar := "PINGCLI_PINGONE_API_SERVICE_HOSTNAME" + + options.PingOneAPIServiceHostnameOption = options.Option{ + CobraParamName: cobraParamName, + CobraParamValue: cobraValue, + DefaultValue: &defaultValue, + EnvVar: envVar, + Flag: &pflag.Flag{ + Name: cobraParamName, + Usage: "Override the service hostname for the PingOne management API.", + Value: cobraValue, + }, + Type: options.ENUM_STRING, + ViperKey: "service.pingone.api.hostname", + } +} + func initPingOneAuthenticationTypeOption() { cobraParamName := "pingone-authentication-type" cobraValue := new(customtypes.PingOneAuthenticationType) diff --git a/internal/testing/testutils/utils.go b/internal/testing/testutils/utils.go index 2b6f3bac..5780aa4f 100644 --- a/internal/testing/testutils/utils.go +++ b/internal/testing/testutils/utils.go @@ -43,6 +43,8 @@ func GetPingOneClientInfo(t *testing.T) *connector.PingOneClientInfo { clientID := os.Getenv(options.PingOneAuthenticationWorkerClientIDOption.EnvVar) clientSecret := os.Getenv(options.PingOneAuthenticationWorkerClientSecretOption.EnvVar) environmentId := GetEnvironmentID() + authServiceHostname := os.Getenv(options.PingOneAuthenticationServiceHostnameOption.EnvVar) + apiServiceHostname := os.Getenv(options.PingOneAPIServiceHostnameOption.EnvVar) regionCode := os.Getenv(options.PingOneRegionCodeOption.EnvVar) sdkRegionCode := management.EnumRegionCode(regionCode) @@ -57,6 +59,14 @@ func GetPingOneClientInfo(t *testing.T) *connector.PingOneClientInfo { RegionCode: &sdkRegionCode, } + if authServiceHostname != "" { + apiConfig.AuthHostnameOverride = &authServiceHostname + } + + if apiServiceHostname != "" { + apiConfig.APIHostnameOverride = &apiServiceHostname + } + // Make empty context for testing ctx := context.Background() diff --git a/internal/testing/testutils_viper/viper_utils.go b/internal/testing/testutils_viper/viper_utils.go index 7d28fcd8..e7de6ecb 100644 --- a/internal/testing/testutils_viper/viper_utils.go +++ b/internal/testing/testutils_viper/viper_utils.go @@ -27,8 +27,11 @@ default: service: pingone: regionCode: %s - authentication: - type: worker + api: + hostname: %s + authentication: + hostname: %s + type: worker worker: clientid: %s clientsecret: %s @@ -110,6 +113,8 @@ func getDefaultConfigFileContents() string { return fmt.Sprintf(defaultConfigFileContentsPattern, outputDirectoryReplacement, os.Getenv(options.PingOneRegionCodeOption.EnvVar), + os.Getenv(options.PingOneAuthenticationServiceHostnameOption.EnvVar), + os.Getenv(options.PingOneAPIServiceHostnameOption.EnvVar), os.Getenv(options.PingOneAuthenticationWorkerClientIDOption.EnvVar), os.Getenv(options.PingOneAuthenticationWorkerClientSecretOption.EnvVar), os.Getenv(options.PingOneAuthenticationWorkerEnvironmentIDOption.EnvVar),