Skip to content

Commit

Permalink
US-498622 - Infinity OAuth env vars for SRS connector (#545)
Browse files Browse the repository at this point in the history
* US-498622 - Infinity OAuth env vars for SRS connector

* US-498622 : Infinity OAuth env vars for SRS connector

---------

Co-authored-by: Davis Walsh <[email protected]>
  • Loading branch information
wieslaw-bartz and APegaDavis authored Apr 3, 2023
1 parent e3a2946 commit 686a06b
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 1 deletion.
26 changes: 26 additions & 0 deletions charts/pega/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,32 @@ pegasearch:
externalURL: "http://srs-service.namespace.svc.cluster.local"
```

To configure authorization for the connection between Pega Infinity and the Search and Reporting Service (SRS) use the OAuth authorization service. For more information, see ['backingservices'](../backingservices). To configure the connection to the authorization service in SRS you must configure the following authorization parameters in the Pega values.yaml as shown in the following table and example:

| Parameter | Description | Default value |
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
| `enabled` | Set the `pegasearch.srsAuth.enabled` to 'true' to use OAuth between Infinity and SRS. | false |
| `url` | Set the `pegasearch.srsAuth.url` value to the URL of the OAuth service endpoint to get the token for SRS. | `""` |
| `clientId` | Set the `pegasearch.srsAuth.clientId` value to the client id used in OAuth service. | `""` |
| `scopes` | Set the `pegasearch.srsAuth.scopes` value to "pega.search:full", the scope set in the OAuth service required to grant access to SRS. | "pega.search:full" |
| `privateKey` | Set the `pegasearch.srsAuth,privateKey` value to the OAuth private PKCS8 key (additionally encoded with base64) used to get an authorization token for the connection between Pega tiers and SRS. | `""` |
| `privateKeyAlgorithm` | Set the `pegasearch.srsAuth.privateKeyAlgorithm` value to the algorithm used to generate a private key used by the OAuth client. Allowed values: RS256 (default), RS384, RS512, ES256, ES384, ES512. | "RS256" |

Example:

```yaml
pegasearch:
externalSearchService: true
externalURL: "http://srs-service.srs-namespace.svc.cluster.local"
srsAuth:
enabled: true
url: "https:/your-authorization-service-host/oauth2/v1/token"
clientId: "your-client-id"
scopes: "pega.search:full"
privateKey: "LS0tLS1CRUdJTiBSU0Eg...<truncated>"
privateKeyAlgorithm: "RS256"
```

Use the below configuration to provision an internally deployed instance of elasticsearch for search functionality within the platform:

Parameter | Description | Default value
Expand Down
10 changes: 10 additions & 0 deletions charts/pega/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,16 @@ dnsConfig:
{{- template "searchURL" $d2 }}
{{- end -}}

{{- define "srsAuthPrivateKey" -}}
{{- if and (.Values.pegasearch.externalSearchService) ((.Values.pegasearch.srsAuth).enabled) }}
{{- if (.Values.pegasearch.srsAuth).privateKey }}
{{- .Values.pegasearch.srsAuth.privateKey | b64enc }}
{{- else }}
{{- fail "A valid entry is required for pegasearch.srsAuth.privateKey, when request authentication mechanism(IDP) is enabled between SRS and Pega Infinity i.e. pegasearch.srsAuth.enabled is true." | quote}}
{{- end }}
{{- end }}
{{- end }}

{{- define "ingressApiVersion" }}
{{- if (semverCompare ">= 1.19.0-0" (trimPrefix "v" .root.Capabilities.KubeVersion.GitVersion)) }}
apiVersion: networking.k8s.io/v1
Expand Down
7 changes: 7 additions & 0 deletions charts/pega/templates/_pega-deployment.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ spec:
value: {{ include "tierClassloaderRetryTimeout" (dict "failureThreshold" $livenessProbeFailureThreshold "periodSeconds" $livenessProbePeriodSeconds ) | quote }}
- name: MAX_RETRIES
value: {{ include "tierClassloaderMaxRetries" (dict "failureThreshold" $livenessProbeFailureThreshold "periodSeconds" $livenessProbePeriodSeconds ) | quote }}
{{- if and (.root.Values.pegasearch.externalSearchService) ((.root.Values.pegasearch.srsAuth).enabled) }}
- name: SERV_AUTH_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: pega-srs-auth-secret
key: privateKey
{{- end }}
envFrom:
- configMapRef:
name: {{ template "pegaEnvironmentConfig" .root }}
Expand Down
18 changes: 17 additions & 1 deletion charts/pega/templates/pega-environment-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,27 @@ data:
# CustomerData schema of the Pega installation
CUSTOMERDATA_SCHEMA: {{ .Values.global.jdbc.customerDataSchema }}
{{- end }}
{{- if .Values.pegasearch.externalSearchService }}
{{- if and (.Values.pegasearch.externalSearchService) (not (.Values.pegasearch.srsAuth).enabled) }}
# Search deployment type so that the engine knows to connect to the search service
PEGA_SEARCH_TYPE: "ExternalSearchService"
# URL to connect to Search and Reporting service
SEARCH_AND_REPORTING_SERVICE_URL: {{ include "pegaSearchURL" $ }}
{{- else if and (.Values.pegasearch.externalSearchService) ((.Values.pegasearch.srsAuth).enabled) }}
# Search deployment type so that the engine knows to connect to the search service
PEGA_SEARCH_TYPE: "ExternalSearchService"
# URL to connect to Search and Reporting service
SEARCH_AND_REPORTING_SERVICE_URL: {{ include "pegaSearchURL" $ }}
# URL of the OAuth endpoint to get the token for Search and Reporting service
SERV_AUTH_URL: "{{ .Values.pegasearch.srsAuth.url }}"
# OAuth scopes to grant permissions for Pega Infinity in Search and Reporting service
# The required value is "pega.search:full"
SERV_AUTH_SCOPES: {{ .Values.pegasearch.srsAuth.scopes | default "pega.search:full" | quote }}
# OAuth Client ID
SERV_AUTH_CLIENT_ID: "{{ .Values.pegasearch.srsAuth.clientId }}"
# Algorithm used to generate a private key used by OAuth client
# Allowed values: RS256, RS384, RS512, ES256, ES384, ES512
# Default value: RS256
SERV_AUTH_PRIVATE_KEY_ALGORITHM: {{ .Values.pegasearch.srsAuth.privateKeyAlgorithm | default "RS256" | quote }}
{{- else }}
# URL to connect to Elastic Search
PEGA_SEARCH_URL: {{ include "pegaSearchURL" $ }}
Expand Down
11 changes: 11 additions & 0 deletions charts/pega/templates/pega-srs-auth-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if and (.Values.pegasearch.externalSearchService) ((.Values.pegasearch.srsAuth).enabled) }}
# Secret for OAuth private key used to get an authorization token for Pega Infinity connection to Search and Reporting Service
apiVersion: v1
kind: Secret
metadata:
name: pega-srs-auth-secret
namespace: {{ .Release.Namespace }}
type: Opaque
data:
privateKey: {{ template "srsAuthPrivateKey" . }}
{{- end }}
3 changes: 3 additions & 0 deletions terratest/src/test/pega/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ package pega
const PegaHelmChartPath = "../../../../charts/pega"
const PegaHelmChartTestsPath = "../../../../terratest/src/test/pega"
const PegaHelmRelease = "pega"

// SRSAuthPrivateKeyExample The example of PKCS8 private key, additionally encoded with base64
const SRSAuthPrivateKeyExample = "TUlJRXZnSUJBREFOQmdrcWhraUc5dzBCQVFFRkFBU0NCS2d3Z2dTa0FnRUFBb0lCQVFDeXBjRlg0SnM4MWhzY2ltNHVRKyswQ0hsQkRxeVZQb3duOG1ldlcyU3U4N1NoTEkzd0s1cTFiMTFrcnZyNzlTQzRna3VNcnlRL2dnN3d5ZG1MY3pwcENjdDBRdDRheERkOU9KejR5UnZXNDFuNTM2b1RpVFYweWVXWktIdlBlandCZ3lmSTA2K25EMkFPRnBmMngyUFRERDhQUFJRRG91Qk04SkV4Q0dGSkRiWTBQb3JybDIvdG43QW5paFV0a3k5MmtaRitKNGx6ZGpqK0pEVW84YkJCeklLN1lucXJHMkI5ZWZWMFdTS0lUV1prc2lqRWpMNjFLbGdaVldMZHhUaXJuS3lSTG5GRDIzS1NTclBaQi8wMWJNNGxyc0JuNGFCYVBhNGlnRVdLNFhicnRrMlVJZURjSkxXREFYcnVaemVhU2QyTDBRbG1UM0k4ajBwbmx6S0JBZ01CQUFFQ2dnRUFLcDB4ZHBYa1VlbTh3OTBkbFRtdFp5T1NVUHVBSFlXekJ5QmlyVWkreHFEcG1IeTVTdTRMMUhYQk1IQXcvSU1uai91OHE4MW5keUsrRDZBR25hWVo2ODVqVXROVWljditkSWRab2xyT29qN1BTclNZckZwUmZ3OWVEbC9DME9ZV2hFSFY3cWpZUUtDQlNEc0pldHRySzMvRFZ3NDV4UGhJU3ZJam9DK2dqVDBwbTE4a0FDejN3VXUyMnFwZHhoQk5iNXd4ZlZJTWpLYzBId3VrcG5mWVBWLzdSYUd4OFRDSmt0c3o4RUk4UUNpY1hNeE92RENaalNWZDJoaGE1eDNZWDNFQjM1cGpwZ0JRMkR1aENLN2pyLzJOMGdtOWpZOCtRMnh0dFdtM1hUQm4wWStvbHdvQXFHS0t2R1JFaGJpTklqQUZ0dGpBaVV6ZmhLcFlrY3lkUlFLQmdRRDlKSkJBcjVPd2pEYk5UY2ZqM2k1QXJ0ZWZKbGpsRmVtU213eGZUVnpId3lnaXhvcks4dytDb2lOaGxqTXBaUmxLZU9keGNSQmk4czNub0RQZjRYL1hkZnNkT1IzalJqUzRzbXhNdThvVzc1RWRxL2kvSEZhelBEUThPRUk5NGpNa2FPdGhoVDZHclEyUzZ2Z1kvbUlTV0ZFTlpOeVRGZ1JhSXZNSGVOQzNud0tCZ1FDMHFmRjVHS1RSdTdhcStJWlZJZ2hXT2ZQTTBXdUorUW80ekNGU1pIbEZXM0tBSDl5ZldGOUZnZ3V0ekpkQVdUN1BhRkZFRE0yYUkxcnV6YkR5R2taNENFd1M5aEdWQ3RXUUYxL1V6ekpsMHhQWUxUWVYzOVBFazZiUC90b3MwUlZYVjU1azhxbkgxQ2MvSzZGSXdJZVVaejJDcWpiWHR3YjVmRFhQejB4aDN3S0JnUUNKK012RzlldUJabXJZSzNTdmRnR3ZyNXhHV2hoSmhFL3lZQisyTWV4SDFNNmpaYU53U2xwQjBTMkhtdDMzeWVxbTlJN3cvYmI0dDI0U3VQYU5KOU1PRkhmeHpaZkVzQmM4TThOamIxY09lVFNXLzR4c1hYM0Q0eVIxVGhTTXRpVTV5eFcvNldmUzc2OWVURU05SENsSDVtc0c2ZHB2TUtqZWwvM3VMS05WOFFLQmdDVGRiSzIyTHFPeGR5UEtGTGM0ZTVVRXZFLzJCOGllcmN4TE14MTU3UmtQQVAxT0F4bnMwWHdBZmx1WG5PRi9sSWFFRmRrWjk3WlZNby82SHZvNERGc2Y3azRNTWloRWpyR1pZMitzVys5Vk0vNXZzMUtoV3JnSkhRZmlUQ2pLL1Z6V1B6Y0FJVTdxWnB2SVRsL25FWU5oMGJaZy8xSGpRaVFVaVhKL0xXbm5Bb0dCQU93dnVOU3lKWlFHSkh3b2JxU0dOalF2RWU5MjRmNkhLZEo3enlhVVVvZmRjS3M4d25IREllcjJLd0d6OWRBb1JuMVNSYjlrOEpVcGJnNXhNQ1RaZGVWc3dwMUdxWkF1dFczRDRZT0Y1cFoxK3ZDaTFyRlBRamtGU1hQUzJYekYyUUpCWTRlUHduWHBabUgzbFhwN2c3V0F3SXZnNWNSUERTckJpaTRRVDVuNw=="
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package pega

import (
"github.com/gruntwork-io/terratest/modules/helm"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
"path/filepath"
"strings"
"testing"
)

func TestPegaDeploymentWithSRSDisabled(t *testing.T) {
var supportedVendors = []string{"k8s", "eks", "gke", "aks"}
var supportedOperations = []string{"deploy", "install-deploy"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {
for _, operation := range supportedOperations {

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
},
}
deploymentYaml := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"})
deployments := strings.Split(deploymentYaml, "---")
for _, deployment := range deployments {
assertNoSRSAuthSettings(t, deployment)
}
}
}
}

func TestPegaDeploymentWithSRSAuthDisabled(t *testing.T) {
var supportedVendors = []string{"k8s", "eks", "gke", "aks"}
var supportedOperations = []string{"deploy", "install-deploy"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {
for _, operation := range supportedOperations {

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
"pegasearch.externalSearchService": "true",
},
}
deploymentYaml := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"})
deployments := strings.Split(deploymentYaml, "---")
for _, deployment := range deployments {
assertNoSRSAuthSettings(t, deployment)
}
}
}
}

func TestPegaDeploymentWithSRSAuthEnabled(t *testing.T) {
var supportedVendors = []string{"k8s", "eks", "gke", "aks"}
var supportedOperations = []string{"deploy", "install-deploy"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {
for _, operation := range supportedOperations {

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
"pegasearch.externalSearchService": "true",
"pegasearch.srsAuth.enabled": "true",
"pegasearch.srsAuth.privateKey": SRSAuthPrivateKeyExample,
},
}
deploymentYaml := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"})
deployments := strings.Split(deploymentYaml, "---")
for _, deployment := range deployments {
assertHasSRSAuthSettings(t, deployment)
}
}
}
}

func assertNoSRSAuthSettings(t *testing.T, pegaTierDeployment string) {
var deployment appsv1.Deployment
UnmarshalK8SYaml(t, pegaTierDeployment, &deployment)
for _, container := range deployment.Spec.Template.Spec.Containers {
for _, envVar := range container.Env {
if "SERV_AUTH_PRIVATE_KEY" == envVar.Name {
require.Fail(t, "container '"+container.Name+"' should not have 'SERV_AUTH_PRIVATE_KEY' environment variable")
}
}
}
}

func assertHasSRSAuthSettings(t *testing.T, pegaTierDeployment string) {
var deployment appsv1.Deployment
UnmarshalK8SYaml(t, pegaTierDeployment, &deployment)
for _, container := range deployment.Spec.Template.Spec.Containers {
hasPrivateKey := false
for _, envVar := range container.Env {
if "SERV_AUTH_PRIVATE_KEY" == envVar.Name {
require.Equal(t, "pega-srs-auth-secret", envVar.ValueFrom.SecretKeyRef.Name)
require.Equal(t, "privateKey", envVar.ValueFrom.SecretKeyRef.Key)
hasPrivateKey = true
}
}
require.True(t, hasPrivateKey, "container '"+container.Name+"' should have 'SERV_AUTH_PRIVATE_KEY' environment variable")
}
}
Loading

0 comments on commit 686a06b

Please sign in to comment.