From a6f6f0dbfbfebe49328ebc648f4c8fab324dcdc7 Mon Sep 17 00:00:00 2001 From: Davis Walsh Date: Wed, 25 Oct 2023 13:07:10 -0400 Subject: [PATCH 01/37] Support custom labels for HPA and PDB (#657) * support custom labels on HPA * support custom labels on PDB --- charts/pega/templates/_pega-pdb.tpl | 4 + charts/pega/templates/_pega_hpa.tpl | 4 + .../pega/data/values_hpa_custom_label.yaml | 15 + .../pega/data/values_pdb_custom_labels.yaml | 293 ++++++++++++++++++ terratest/src/test/pega/pega-tier-hpa_test.go | 261 ++++++++++------ terratest/src/test/pega/pega-tier-pdb_test.go | 65 ++++ 6 files changed, 542 insertions(+), 100 deletions(-) create mode 100644 terratest/src/test/pega/data/values_hpa_custom_label.yaml create mode 100644 terratest/src/test/pega/data/values_pdb_custom_labels.yaml diff --git a/charts/pega/templates/_pega-pdb.tpl b/charts/pega/templates/_pega-pdb.tpl index f76eaccd9..d9423b6ae 100644 --- a/charts/pega/templates/_pega-pdb.tpl +++ b/charts/pega/templates/_pega-pdb.tpl @@ -10,6 +10,10 @@ kind: PodDisruptionBudget metadata: name: {{ .name }}-pdb namespace: {{ .root.Release.Namespace }} +{{- if .pdb.labels }} + labels: +{{ toYaml .pdb.labels | indent 4 }} +{{- end }} spec: {{- if .pdb.minAvailable }} minAvailable: {{ .pdb.minAvailable }} diff --git a/charts/pega/templates/_pega_hpa.tpl b/charts/pega/templates/_pega_hpa.tpl index 0857131db..7bf84bca6 100644 --- a/charts/pega/templates/_pega_hpa.tpl +++ b/charts/pega/templates/_pega_hpa.tpl @@ -10,6 +10,10 @@ kind: HorizontalPodAutoscaler metadata: name: {{ .name | quote}} namespace: {{ .root.Release.Namespace }} +{{- if .hpa.labels }} + labels: +{{ toYaml .hpa.labels | indent 4 }} +{{- end }} spec: scaleTargetRef: apiVersion: apps/v1 diff --git a/terratest/src/test/pega/data/values_hpa_custom_label.yaml b/terratest/src/test/pega/data/values_hpa_custom_label.yaml new file mode 100644 index 000000000..935407c7f --- /dev/null +++ b/terratest/src/test/pega/data/values_hpa_custom_label.yaml @@ -0,0 +1,15 @@ +--- +global: + tier: + - name: "web" + hpa: + enabled: true + labels: + web-label: "somevalue" + web-other-label: "someothervalue" + - name: "batch" + hpa: + enabled: true + labels: + batch-label: "batchlabel" + batch-other-label: "anothervalue" diff --git a/terratest/src/test/pega/data/values_pdb_custom_labels.yaml b/terratest/src/test/pega/data/values_pdb_custom_labels.yaml new file mode 100644 index 000000000..e06275c8c --- /dev/null +++ b/terratest/src/test/pega/data/values_pdb_custom_labels.yaml @@ -0,0 +1,293 @@ +--- +global: + # This values.yaml file is an example. For more information about + # each configuration option, see the project readme. + + # Enter your Kubernetes provider. + provider: "YOUR_KUBERNETES_PROVIDER" + + deployment: + # The name specified will be used to prefix all of the Pega pods (replacing "pega" with something like "app1-dev"). + name: "pega" + + # Deploy Pega nodes + actions: + execute: "deploy" + + # Provide JDBC connection information to the Pega relational database + # If you are installing or upgrading on IBM DB2, update the udb.conf file in the /charts/pega/charts/installer/config/udb directory with any additional connection properties. + jdbc: + # url Valid values are: + # + # Oracle jdbc:oracle:thin:@//localhost:1521/dbName + # IBM DB/2 z / OS jdbc:db2://localhost:50000/dbName + # IBM DB/2 jdbc:db2://localhost:50000/dbName:fullyMaterializeLobData=true;fullyMaterializeInputStreams=true; + # progressiveStreaming=2;useJDBC4ColumnNameAndLabelSemantics=2; + # SQL Server jdbc:sqlserver://localhost:1433;databaseName=dbName;selectMethod=cursor;sendStringParametersAsUnicode=false + # PostgreSQL jdbc:postgresql://localhost:5432/dbName + url: "YOUR_JDBC_URL" + # driverClass -- jdbc class. Valid values are: + # + # Oracle oracle.jdbc.OracleDriver + # IBM DB/2 com.ibm.db2.jcc.DB2Driver + # SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver + # PostgreSQL org.postgresql.Driver + driverClass: "YOUR_JDBC_DRIVER_CLASS" + # pega.database.type Valid values are: mssql, oracledate, udb, db2zos, postgres + dbType: "YOUR_DATABASE_TYPE" + # For databases that use multiple JDBC driver files (such as DB2), specify comma separated values for 'driverUri' + driverUri: "YOUR_JDBC_DRIVER_URI" + username: "YOUR_JDBC_USERNAME" + password: "YOUR_JDBC_PASSWORD" + # CUSTOM CONNECTION PROPERTIES + # Add a list of ; delimited connections properties. The list must end with ; + # For example: connectionProperties=user=usr;password=pwd; + connectionProperties: "" + rulesSchema: "YOUR_RULES_SCHEMA" + dataSchema: "YOUR_DATA_SCHEMA" + customerDataSchema: "" + + # If using a custom Docker registry, supply the credentials here to pull Docker images. + docker: + registry: + url: "YOUR_DOCKER_REGISTRY" + username: "YOUR_DOCKER_REGISTRY_USERNAME" + password: "YOUR_DOCKER_REGISTRY_PASSWORD" + # Docker image information for the Pega docker image, containing the application server. + pega: + image: "pegasystems/pega" + + # Upgrade specific properties + upgrade: + # Configure only for aks/pks + # Run "kubectl cluster-info" command to get the service host and https service port of kubernetes api server. + # Example - Kubernetes master is running at https://: + kube-apiserver: + serviceHost: "API_SERVICE_ADDRESS" + httpsServicePort: "SERVICE_PORT_HTTPS" + + # Specify the Pega tiers to deploy + tier: + - name: "web" + # Create a an interactive tier for web users. This tier uses + # the WebUser node type and will be exposed via a service to + # the load balancer. + nodeType: "WebUser" + + # Pega requestor specific properties + requestor: + # Inactivity time after which requestor is passivated + passivationTimeSec: 900 + + service: + # For help configuring the service block, see the Helm chart documentation + # https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#service + port: 80 + targetPort: 8080 + + ingress: + # For help configuring the ingress block including TLS, see the Helm chart documentation + # https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#ingress + + # Enter the domain name to access web nodes via a load balancer. + # e.g. web.mypega.example.com + domain: "YOUR_WEB_NODE_DOMAIN" + tls: + # Enable TLS encryption + enabled: true + # secretName: + # useManagedCertificate: false + # ssl_annotation: + + replicas: 1 + javaOpts: "" + pegaDiagnosticUser: "" + pegaDiagnosticPassword: "" + + deploymentStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + + livenessProbe: + port: 8081 + + # Optionally overridde default resource specifications + # cpuRequest: 2 + # memRequest: "12Gi" + # cpuLimit: 4 + # memLimit: "12Gi" + # initialHeap: "4096m" + # maxHeap: "8192m" + + # To configure an alternative user for custom image, set value for runAsUser. + # See, https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#security-context + # securityContext: + # runAsUser: 9001 + + hpa: + enabled: true + + # Set enabled to true to include a Pod Disruption Budget for this tier + pdb: + enabled: true + minAvailable: 1 + labels: + weblabel: "somevalue" + anotherlabel: "anothervalue" + + - name: "batch" + # Create a background tier for batch processing. This tier uses + # a collection of background node types and will not be exposed to + # the load balancer. + nodeType: "BackgroundProcessing,Search,Batch,RealTime,Custom1,Custom2,Custom3,Custom4,Custom5,BIX" + + replicas: 1 + javaOpts: "" + + pegaDiagnosticUser: "" + pegaDiagnosticPassword: "" + + deploymentStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + + livenessProbe: + port: 8081 + + # To configure an alternative user for your custom image, set value for runAsUser + # See, https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#security-context + # securityContext: + # runAsUser: 9001 + + hpa: + enabled: true + + # Set enabled to true to include a Pod Disruption Budget for this tier + pdb: + enabled: true + minAvailable: 1 + labels: + batchlabel: "batchvalue" + anotherbatchlabel: "batchvalue2" + + - name: "stream" + # Create a stream tier for queue processing. This tier deploys + # as a stateful set to ensure durability of queued data. It may + # be optionally exposed to the load balancer. + nodeType: "Stream" + + # Pega requestor specific properties + requestor: + # Inactivity time after which requestor is passivated + passivationTimeSec: 900 + + service: + port: 7003 + targetPort: 7003 + + # If a nodeSelector is required for this or any tier, it may be specified here: + # nodeSelector: + # disktype: ssd + + ingress: + # Enter the domain name to access web nodes via a load balancer. + # e.g. web.mypega.example.com + domain: "YOUR_STREAM_NODE_DOMAIN" + tls: + # Enable TLS encryption + enabled: true + # secretName: + # useManagedCertificate: false + # ssl_annotation: + + livenessProbe: + port: 8081 + + # To configure an alternative user for your custom image, set value for runAsUser + # See, https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#security-context + # securityContext: + # runAsUser: 9001 + + replicas: 2 + + volumeClaimTemplate: + resources: + requests: + storage: 5Gi + + # Set enabled to true to include a Pod Disruption Budget for this tier + pdb: + enabled: true + minAvailable: 1 + # maxUnavailable: "50%" + +# External services + +# Cassandra automatic deployment settings. +cassandra: + enabled: true + persistence: + enabled: true + resources: + requests: + memory: "4Gi" + cpu: 2 + limits: + memory: "8Gi" + cpu: 4 + +# DDS (external Cassandra) connection settings. +# These settings should only be modified if you are using a custom Cassandra deployment. +dds: + externalNodes: "" + port: "9042" + username: "dnode_ext" + password: "dnode_ext" + clientEncryption: false + trustStore: "" + trustStorePassword: "" + keyStore: "" + keyStorePassword: "" + +# Elasticsearch deployment settings. +# Note: This Elasticsearch deployment is used for Pega search, and is not the same Elasticsearch deployment used by the EFK stack. +# These search nodes will be deployed regardless of the Elasticsearch configuration above. +# Refer to README document to configure `Search and Reporting Service` as a search functionality provider under this section. +pegasearch: + image: "pegasystems/search" + memLimit: "3Gi" + replicas: 1 + +# Pega Installer settings. +installer: + image: "YOUR_INSTALLER_IMAGE:TAG" + # Set the initial administrator@pega.com password for your installation. This will need to be changed at first login. + # The adminPassword value cannot start with "@". + adminPassword: "ADMIN_PASSWORD" + # Upgrade specific properties + upgrade: + # Type of upgrade + # Valid upgradeType values are 'in-place' , 'zero-downtime' , 'custom' , 'out-of-place-rules' , 'out-of-place-data' . + upgradeType: "in-place" + # Specify a name for a target rules schema that the upgrade process creates for patches and upgrades. + targetRulesSchema: "" + # Specify a name for a target data schema that the upgrade process creates for patches and upgrades. + # For postgres databases that you are upgrading from Pega Infinity version 8.4.0 and later + # And for Oracle databases that you are upgrading from Pega Infinity version 8.4.3 and later. + targetDataSchema: "" + +# Hazelcast settings (applicable from Pega 8.6) +hazelcast: + image: "YOUR_HAZELCAST_IMAGE:TAG" + # Setting below to true will deploy the infinity in client-server Hazelcast model + enabled: false + # No. of initial members to join + replicas: 3 + # UserName to be used in client-server Hazelcast model for authentication + username: "" + # Password to be used in client-server Hazelcast model for authentication + password: "" diff --git a/terratest/src/test/pega/pega-tier-hpa_test.go b/terratest/src/test/pega/pega-tier-hpa_test.go index 3b65e8d24..9e4facd75 100644 --- a/terratest/src/test/pega/pega-tier-hpa_test.go +++ b/terratest/src/test/pega/pega-tier-hpa_test.go @@ -8,15 +8,15 @@ import ( "github.com/gruntwork-io/terratest/modules/helm" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/api/resource" autoscaling "k8s.io/api/autoscaling/v2beta2" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" ) func TestPegaTierHPA(t *testing.T) { - var supportedVendors = []string{"k8s", "openshift", "eks","gke","aks","pks"} - var supportedOperations = []string{"deploy","install-deploy","upgrade-deploy"} - var deploymentNames = []string{"pega","myapp-dev"} + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} helmChartPath, err := filepath.Abs(PegaHelmChartPath) require.NoError(t, err) @@ -25,48 +25,50 @@ func TestPegaTierHPA(t *testing.T) { for _, operation := range supportedOperations { - for _, depName := range deploymentNames { + for _, depName := range deploymentNames { - fmt.Println(vendor + "-" + operation) + fmt.Println(vendor + "-" + operation) - var options = &helm.Options{ - SetValues: map[string]string{ - "global.deployment.name": depName, - "global.provider": vendor, - "global.actions.execute": operation, + var options = &helm.Options{ + SetValues: map[string]string{ + "global.deployment.name": depName, + "global.provider": vendor, + "global.actions.execute": operation, "installer.upgrade.upgradeType": "zero-downtime", - }, - } - - yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}) - verifyPegaHPAs(t, yamlContent, options, []hpa{ - { - name: getObjName(options, "-web-hpa"), - targetRefName: getObjName(options, "-web"), - kind: "Deployment", - apiversion: "apps/v1", - cpu: true, - cpuValue: parseResourceValue(t, "2.55"), - }, - { - name: getObjName(options, "-batch-hpa"), - targetRefName: getObjName(options, "-batch"), - kind: "Deployment", - apiversion: "apps/v1", - cpu: true, - cpuValue: parseResourceValue(t, "2.55"), - }, - }) - } + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}) + verifyPegaHPAs(t, yamlContent, options, []hpa{ + { + name: getObjName(options, "-web-hpa"), + targetRefName: getObjName(options, "-web"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + }, + { + name: getObjName(options, "-batch-hpa"), + targetRefName: getObjName(options, "-batch"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + }, + }) + } } } } +func TestPegaTierHPAWithCustomLabel(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} -func TestPegaTierHPADisableTarget(t *testing.T) { - var supportedVendors = []string{"k8s", "openshift", "eks","gke","aks","pks"} - var supportedOperations = []string{"deploy","install-deploy","upgrade-deploy"} - var deploymentNames = []string{"pega","myapp-dev"} + expectedWebLabels := map[string]string{"web-label": "somevalue", "web-other-label": "someothervalue"} + expectedBatchLabels := map[string]string{"batch-label": "batchlabel", "batch-other-label": "anothervalue"} helmChartPath, err := filepath.Abs(PegaHelmChartPath) require.NoError(t, err) @@ -78,48 +80,100 @@ func TestPegaTierHPADisableTarget(t *testing.T) { for _, operation := range supportedOperations { - for _, depName := range deploymentNames { - fmt.Println(vendor + "-" + operation) + for _, depName := range deploymentNames { - var options = &helm.Options{ - SetValues: map[string]string{ - "global.deployment.name": depName, - "global.provider": vendor, - "global.actions.execute": operation, + fmt.Println(vendor + "-" + operation) + + var options = &helm.Options{ + SetValues: map[string]string{ + "global.deployment.name": depName, + "global.provider": vendor, + "global.actions.execute": operation, "installer.upgrade.upgradeType": "zero-downtime", - }, - } - - - yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}, "--values", testsPath+"/data/values_hpa_disabletarget.yaml") - verifyPegaHPAs(t, yamlContent, options, []hpa{ - { - name: getObjName(options, "-web-hpa"), - targetRefName: getObjName(options, "-web"), - kind: "Deployment", - apiversion: "apps/v1", - mem: true, - memPercent: 85, - }, - { - name: getObjName(options, "-batch-hpa"), - targetRefName: getObjName(options, "-batch"), - kind: "Deployment", - apiversion: "apps/v1", - cpu: true, - cpuValue: parseResourceValue(t, "2.55"), - }, - }) - } + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}, "--values", testsPath+"/data/values_hpa_custom_label.yaml") + verifyPegaHPAs(t, yamlContent, options, []hpa{ + { + name: getObjName(options, "-web-hpa"), + targetRefName: getObjName(options, "-web"), + kind: "Deployment", + apiversion: "apps/v1", + labels: expectedWebLabels, + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + }, + { + name: getObjName(options, "-batch-hpa"), + targetRefName: getObjName(options, "-batch"), + kind: "Deployment", + apiversion: "apps/v1", + labels: expectedBatchLabels, + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + }, + }) + } } } } +func TestPegaTierHPADisableTarget(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + + testsPath, err := filepath.Abs(PegaHelmChartTestsPath) + require.NoError(t, err) + + for _, vendor := range supportedVendors { + + for _, operation := range supportedOperations { + + for _, depName := range deploymentNames { + fmt.Println(vendor + "-" + operation) + + var options = &helm.Options{ + SetValues: map[string]string{ + "global.deployment.name": depName, + "global.provider": vendor, + "global.actions.execute": operation, + "installer.upgrade.upgradeType": "zero-downtime", + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}, "--values", testsPath+"/data/values_hpa_disabletarget.yaml") + verifyPegaHPAs(t, yamlContent, options, []hpa{ + { + name: getObjName(options, "-web-hpa"), + targetRefName: getObjName(options, "-web"), + kind: "Deployment", + apiversion: "apps/v1", + mem: true, + memPercent: 85, + }, + { + name: getObjName(options, "-batch-hpa"), + targetRefName: getObjName(options, "-batch"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + }, + }) + } + } + } +} func TestPegaTierOverrideValues(t *testing.T) { var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} - var deploymentNames = []string{"pega","myapp-dev"} + var deploymentNames = []string{"pega", "myapp-dev"} helmChartPath, err := filepath.Abs(PegaHelmChartPath) require.NoError(t, err) @@ -131,38 +185,38 @@ func TestPegaTierOverrideValues(t *testing.T) { for _, operation := range supportedOperations { - for _, depName := range deploymentNames { - fmt.Println(vendor + "-" + operation + "-" + depName) + for _, depName := range deploymentNames { + fmt.Println(vendor + "-" + operation + "-" + depName) - var options = &helm.Options{ - SetValues: map[string]string{ - "global.provider": vendor, - "global.actions.execute": operation, + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, "installer.upgrade.upgradeType": "zero-downtime", - }, - } - - yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}, "--values", testsPath+"/data/values_hpa_overridevalues.yaml") - verifyPegaHPAs(t, yamlContent, options, []hpa{ - { - name: getObjName(options, "-web-hpa"), - targetRefName: getObjName(options, "-web"), - kind: "Deployment", - apiversion: "apps/v1", - cpu: true, - cpuValue: parseResourceValue(t, "4.13"), - mem: true, - memPercent: 42, - }, - { - name: getObjName(options, "-batch-hpa"), - targetRefName: getObjName(options, "-batch"), - kind: "Deployment", - apiversion: "apps/v1", - cpu: true, - cpuPercent: 24, - }, - }) + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}, "--values", testsPath+"/data/values_hpa_overridevalues.yaml") + verifyPegaHPAs(t, yamlContent, options, []hpa{ + { + name: getObjName(options, "-web-hpa"), + targetRefName: getObjName(options, "-web"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuValue: parseResourceValue(t, "4.13"), + mem: true, + memPercent: 42, + }, + { + name: getObjName(options, "-batch-hpa"), + targetRefName: getObjName(options, "-batch"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuPercent: 24, + }, + }) } } } @@ -210,6 +264,12 @@ func verifyPegaHpa(t *testing.T, hpaObj *autoscaling.HorizontalPodAutoscaler, ex currentMetricIndex++ } + for key, expectedValue := range expectedHpa.labels { + actual := hpaObj.Labels[key] + require.NotNil(t, actual) + require.Equal(t, expectedValue, actual) + } + require.Equal(t, int32(5), hpaObj.Spec.MaxReplicas) } @@ -218,6 +278,7 @@ type hpa struct { targetRefName string kind string apiversion string + labels map[string]string cpu bool cpuValue resource.Quantity cpuPercent int32 diff --git a/terratest/src/test/pega/pega-tier-pdb_test.go b/terratest/src/test/pega/pega-tier-pdb_test.go index b8ddb1a4f..0997267ce 100644 --- a/terratest/src/test/pega/pega-tier-pdb_test.go +++ b/terratest/src/test/pega/pega-tier-pdb_test.go @@ -65,6 +65,64 @@ func TestPegaTierPDBEnabled(t *testing.T) { } } +func TestPegaTierPDBWithCustomLabels(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + + webPDBLabels := map[string]string{"weblabel": "somevalue", "anotherlabel": "anothervalue"} + batchPDBLabels := map[string]string{"batchlabel": "batchvalue", "anotherbatchlabel": "batchvalue2"} + + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + + testsPath, err := filepath.Abs(PegaHelmChartTestsPath) + require.NoError(t, err) + + for _, vendor := range supportedVendors { + + for _, operation := range supportedOperations { + + for _, depName := range deploymentNames { + + fmt.Println(vendor + "-" + operation) + + var options = &helm.Options{ + SetValues: map[string]string{ + "global.deployment.name": depName, + "global.provider": vendor, + "global.actions.execute": operation, + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-pdb.yaml"}, "--values", testsPath+"/data/values_pdb_custom_labels.yaml") + verifyPegaPDBs(t, yamlContent, options, []pdb{ + { + name: getObjName(options, "-web-pdb"), + kind: "PodDisruptionBudget", + apiversion: "policy/v1beta1", + labels: webPDBLabels, + minAvailable: 1, + }, + { + name: getObjName(options, "-batch-pdb"), + kind: "PodDisruptionBudget", + apiversion: "policy/v1beta1", + labels: batchPDBLabels, + minAvailable: 1, + }, + { + name: getObjName(options, "-stream-pdb"), + kind: "PodDisruptionBudget", + apiversion: "policy/v1beta1", + minAvailable: 1, + }, + }) + } + } + } +} + // TestPegaTierPDBDisabled - verify that a PodDisruptionBudget is not created when global.tier.pdb.enabled=false func TestPegaTierPDBDisabled(t *testing.T) { var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} @@ -121,11 +179,18 @@ func verifyPegaPdb(t *testing.T, pegaPdbObj *v1beta1.PodDisruptionBudget, expect //kubernetes 1.21 or higher, and we should adjust this test to use the policy/v1 API version require.Equal(t, pegaPdbObj.TypeMeta.APIVersion, expectedPdb.apiversion) require.Equal(t, expectedPdb.minAvailable, pegaPdbObj.Spec.MinAvailable.IntVal) + + for key, expectedValue := range expectedPdb.labels { + actual := pegaPdbObj.Labels[key] + require.NotNil(t, actual) + require.Equal(t, expectedValue, actual) + } } type pdb struct { name string kind string apiversion string + labels map[string]string minAvailable int32 } From 0200cd316e7b60262e3f275075f784599796a379 Mon Sep 17 00:00:00 2001 From: vnihal72 <79415342+vnihal72@users.noreply.github.com> Date: Fri, 27 Oct 2023 12:17:17 +0530 Subject: [PATCH 02/37] Updated Hazelcast heap setting to derive from available RAM (#658) * Updated Hazelcast heap setting to derive from available RAM * Test case fixed --------- Co-authored-by: vermn1 Co-authored-by: MadhuriArugula --- charts/pega/charts/hazelcast/values.yaml | 4 ++-- .../test/pega/clustering-service-environment-config_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/pega/charts/hazelcast/values.yaml b/charts/pega/charts/hazelcast/values.yaml index 61b81441c..56079d303 100644 --- a/charts/pega/charts/hazelcast/values.yaml +++ b/charts/pega/charts/hazelcast/values.yaml @@ -38,8 +38,8 @@ client: clusterName: "PRPC" # Server side settings for Hazelcast server: - java_opts: "-Xms820m -Xmx820m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof - -XX:+UseParallelGC -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m" + java_opts: "-XX:MaxRAMPercentage=80.0 -XX:InitialRAMPercentage=80.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof + -XX:+UseParallelGC -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m -XshowSettings:vm" jmx_enabled: "true" health_monitoring_level: "OFF" operation_generic_thread_count: "" diff --git a/terratest/src/test/pega/clustering-service-environment-config_test.go b/terratest/src/test/pega/clustering-service-environment-config_test.go index 53470fb74..cca1a2c0f 100644 --- a/terratest/src/test/pega/clustering-service-environment-config_test.go +++ b/terratest/src/test/pega/clustering-service-environment-config_test.go @@ -49,7 +49,7 @@ func VerifyClusteringServiceEnvironmentConfig(t *testing.T, yamlContent string, UnmarshalK8SYaml(t, statefulInfo, &clusteringServiceEnvConfigMap) clusteringServiceEnvConfigData := clusteringServiceEnvConfigMap.Data require.Equal(t, clusteringServiceEnvConfigData["NAMESPACE"], "default") - require.Equal(t, clusteringServiceEnvConfigData["JAVA_OPTS"], "-Xms820m -Xmx820m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof -XX:+UseParallelGC -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m") + require.Equal(t, clusteringServiceEnvConfigData["JAVA_OPTS"], "-XX:MaxRAMPercentage=80.0 -XX:InitialRAMPercentage=80.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof -XX:+UseParallelGC -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m -XshowSettings:vm") require.Equal(t, clusteringServiceEnvConfigData["SERVICE_NAME"], "clusteringservice-service") require.Equal(t, clusteringServiceEnvConfigData["MIN_CLUSTER_SIZE"], "3") require.Equal(t, clusteringServiceEnvConfigData["JMX_ENABLED"], "true") From f8737ef3246fd3ce97d8ac3958317058c5957906 Mon Sep 17 00:00:00 2001 From: Divyansh Bhowmick <126799799+bhowd1@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:23:52 +0530 Subject: [PATCH 03/37] US-563606-1: Upgrade ES Server Version 7.10.2 to 7.17.9 for Internal Elasticsearch (#647) * US-563606-1: Upgrade ES Server Default Version * Updated Makefile to update certs in case of TLS * Updated make file for external secrets update * Removed legacy flag * Updated README file. * Updated Readme * Updated Readme * Update comment to explain es helm & server version * Lint changes * Updated Readme and Make file * Lint fixes * Lint fixes --------- Co-authored-by: MadhuriArugula --- charts/backingservices/Makefile | 12 +++++++++++ charts/backingservices/charts/srs/README.md | 24 +++++++++++++++++++-- charts/backingservices/requirements.yaml | 3 ++- charts/backingservices/values.yaml | 7 +++--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/charts/backingservices/Makefile b/charts/backingservices/Makefile index fbdc4e663..e83a7aa70 100644 --- a/charts/backingservices/Makefile +++ b/charts/backingservices/Makefile @@ -26,3 +26,15 @@ purge-es-secrets: external-es-secrets: kubectl create secret generic srs-certificates --from-file=$(PATH_TO_CERTIFICATE) --namespace=$(NAMESPACE) + +purge-srs-secrets: + kubectl delete secrets srs-certificates --namespace=$(NAMESPACE) || true + +purge-secrets: purge-es-secrets + make purge-srs-secrets + +update-secrets: purge-secrets + make es-prerequisite + +update-external-es-secrets: purge-srs-secrets + make external-es-secrets \ No newline at end of file diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index 1c2a5fbf4..feffbb959 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -57,7 +57,7 @@ To deploy Pega Platform with the SRS backing service, the SRS helm chart require | `deploymentName` | Specify the name of your SRS cluster. Your deployment creates resources prefixed with this string. This is also the service name for the SRS. | | `srsRuntime` | Use this section to define specific resource configuration options like image, replica count, cpu and memory resource settings in the SRS. | | `busybox` | When provisioning an internally managed Elasticsearch cluster, you can customize the location and pull policy of the Alpine image used during the deployment process by specifying `busybox.image` and `busybox.imagePullPolicy`. | -| `elasticsearch` | Define the elasticsearch cluster configurations. The [Elasticsearch](https://github.com/helm/charts/tree/master/stable/elasticsearch/values.yaml) chart defines the values for Elasticsearch provisioning in the SRS cluster. For internally provisioned Elasticsearch the default version is set to `7.10.2`. Set the `elasticsearch.imageTag` parameter in values.yaml to `7.16.3` to use this supported version in the SRS cluster. | +| `elasticsearch` | Define the elasticsearch cluster configurations. The [Elasticsearch](https://github.com/helm/charts/tree/master/stable/elasticsearch/values.yaml) chart defines the values for Elasticsearch provisioning in the SRS cluster. For internally provisioned Elasticsearch the default version is set to `7.17.9`. Set the `elasticsearch.imageTag` parameter in values.yaml to `7.16.3` to use this supported version in the SRS cluster. | | `k8sProvider` | Specify your Kubernetes provider name. Supported values are [`eks`, `aks`, `minikube`, `gke`, `openshift`, `pks`].. ### Enabling security between SRS and Elasticsearch @@ -78,7 +78,7 @@ make external-es-secrets NAMESPACE=pegabackingservices ELASTICSEARCH_VERSION=7.1 | `tls` | Set to `true` to enable the SRS service to authenticate to your organization's available Elasticsearch service. | | `esCredentials.username` | Enter the username for your available Elasticsearch service. This username value must match the values you set in the connection info section of esCredentials. | | `esCredentials.password` | Enter the required password for your available Elasticsearch service. This password value must match the values you set in the connection info section of esCredentials. | -| `srsStorage.provisionInternalESCluster` |
  • Set to false to disable this parameter and connect to your available Elasticsearch service from the SRS cluster. Disabling this setting requires you to provide connectivity details to your organization's external Elasticsearch service along with an appropriate TLS certificate with which you authenticate with the service. To pass the required certificate to the cluster using a secrets file, run the command, `$ make external-es-secrets NAMESPACE= ELASTICSEARCH_VERSION= PATH_TO_CERTIFICATE=`.
  • where NAMESPACE references your deployment namespace of the SRS cluster, `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use, and `PATH_TO_CERTIFICATE` points to the location where you copied the required certificates on your location machine.
| +| `srsStorage.provisionInternalESCluster` |
  • Set to false to disable this parameter and connect to your available Elasticsearch service from the SRS cluster. Disabling this setting requires you to provide connectivity details to your organization's external Elasticsearch service along with an appropriate TLS certificate with which you authenticate with the service. To pass the required certificate to the cluster using a secrets file, run the command, `$ make external-es-secrets NAMESPACE= ELASTICSEARCH_VERSION= PATH_TO_CERTIFICATE=`.
  • where NAMESPACE references your deployment namespace of the SRS cluster, `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use, and `PATH_TO_CERTIFICATE` points to the location where you copied the required certificates on your location machine.
  • Use the following Make command to update the SRS and External Elasticsearch certificates: `$ make update-external-es-secrets NAMESPACE= PATH_TO_CERTIFICATE=`.
| | `domain` | Enter the DNS entry associated with your external Elasticsearch service. | Note: Only .p12 and .jks certificates are supported. @@ -157,3 +157,23 @@ srs: requireInternetAccess: false ``` +### Steps to upgrade SRS (with Internal Elasticsearch) to Kubernetes Cluster Version >=1.25 + +To support SRS on Kubernetes version >=1.25 you need to use Elasticsearch server version 7.17.9. If you are using an earlier version (7.10.2 or 7.16.3) of Elasticsearch in your deployment, to upgrade to 7.17.9, you need to perform the following steps: +1. Get the latest backingservices Helm chart which supports `k8s version >=1.25`. +2. Update the SRS and Elasticsearch certificates by running the following Make command: + ```bash + make update-secrets NAMESPACE= ELASTICSEARCH_VERSION=7.17.9 + ``` +3. To use Elasticsearch version 7.17.9, inspect the values.yaml file from the latest backingservices helm chart and confirm if the imageTag parameter in the values.yaml file is same as in the example below: + ```yaml + elasticsearch: + imageTag: 7.17.9 + ``` +4. Upgrade your deployment using the following Helm command: + ```bash + helm upgrade backingservices pega/backingservices --version --namespace --values + ``` +5. Verify that the Elasticsearch pods status is Running. +6. Restart the old SRS pods and verify that the status of the new pods is Running. +7. Verify all pods are running and working as expected. \ No newline at end of file diff --git a/charts/backingservices/requirements.yaml b/charts/backingservices/requirements.yaml index 891dcd358..5bd71adf5 100644 --- a/charts/backingservices/requirements.yaml +++ b/charts/backingservices/requirements.yaml @@ -3,9 +3,10 @@ # NOTE: For kubernetes version >=1.25 or Elasticsearch version 7.17.9, # use 7.17.3 for the elasticsearch 'version' parameter below (for Elasticsearch version 7.17.9, you will still use 7.17.9 in the backingservices values.yaml). # To disable deploying Elasticsearch in SRS, set the 'srs.srsStorage.provisionInternalESCluster' parameter in backingservices values.yaml to false. +# The dependencies.version parameter refers to the Elastcisearch Helm chart version, not Elasticsearch server version. dependencies: - name: elasticsearch - version: "7.10.2" + version: "7.17.3" repository: https://helm.elastic.co/ condition: srs.srsStorage.provisionInternalESCluster - name: constellation diff --git a/charts/backingservices/values.yaml b/charts/backingservices/values.yaml index 502574921..b4a5cce18 100644 --- a/charts/backingservices/values.yaml +++ b/charts/backingservices/values.yaml @@ -80,9 +80,10 @@ constellation: # based on helm charts defined at https://github.com/elastic/helm-charts/tree/master/elasticsearch and may be modified # as per runtime and storage requirements. elasticsearch: - # for internally provisioned elasticsearch version is set to 7.10.2. Use this imageTag configuration to update it to 7.16.3 or - # 7.17.9 if required. However, we strongly recommend to use version 7.17.9. - imageTag: 7.10.2 + # For internally provisioned Elasticsearch server, the imageTag parameter is set by default to 7.17.9, which is the recommended Elasticsearch server version + # for k8s version >= 1.25. + # Use this parameter to change it to 7.10.2 or 7.16.3 for k8s version < 1.25 and make sure to update the Elasticsearch helm chart version in requirements.yaml. + imageTag: 7.17.9 # Permit co-located instances for solitary minikube virtual machines. antiAffinity: "soft" # Shrink default JVM heap. From fd4bf798f6e669b081881c1e2ee3a7465459d61b Mon Sep 17 00:00:00 2001 From: vargm Date: Fri, 27 Oct 2023 16:21:49 +0100 Subject: [PATCH 04/37] Issue #643: set same default initial and max heap value (#646) Co-authored-by: Davis Walsh --- charts/pega/README.md | 2 +- charts/pega/templates/_helpers.tpl | 2 +- terratest/src/test/pega/pega-tier-deployment_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/pega/README.md b/charts/pega/README.md index b8e8fba5b..e48632596 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -451,7 +451,7 @@ Parameter | Description | Defau `cpuLimit` | CPU limit for pods in the current tier. | `4` `memRequest` | Initial memory request for pods in the current tier. | `12Gi` `memLimit` | Memory limit for pods in the current tier. | `12Gi` -`initialHeap` | Specify the initial heap size of the JVM. | `4096m` +`initialHeap` | Specify the initial heap size of the JVM. | `8192m` `maxHeap` | Specify the maximum heap size of the JVM. | `8192m` ### JVM Arguments diff --git a/charts/pega/templates/_helpers.tpl b/charts/pega/templates/_helpers.tpl index 29232c51a..dfa3a714b 100644 --- a/charts/pega/templates/_helpers.tpl +++ b/charts/pega/templates/_helpers.tpl @@ -241,7 +241,7 @@ until cqlsh -u {{ $cassandraUser | quote }} -p {{ $cassandraPassword | quote }} {{- if .node.initialHeap }} value: "{{ .node.initialHeap }}" {{- else }} - value: "4096m" + value: "8192m" {{- end }} # Maximum JVM heap size, equivalent to -Xmx - name: MAX_HEAP diff --git a/terratest/src/test/pega/pega-tier-deployment_test.go b/terratest/src/test/pega/pega-tier-deployment_test.go index 5fde1ae94..39ed19f46 100644 --- a/terratest/src/test/pega/pega-tier-deployment_test.go +++ b/terratest/src/test/pega/pega-tier-deployment_test.go @@ -198,7 +198,7 @@ func VerifyDeployment(t *testing.T, pod *k8score.PodSpec, expectedSpec pegaDeplo require.Equal(t, "", pod.Containers[0].Env[envIndex].Value) envIndex++ require.Equal(t, "INITIAL_HEAP", pod.Containers[0].Env[envIndex].Name) - require.Equal(t, "4096m", pod.Containers[0].Env[envIndex].Value) + require.Equal(t, "8192m", pod.Containers[0].Env[envIndex].Value) envIndex++ require.Equal(t, "MAX_HEAP", pod.Containers[0].Env[envIndex].Name) require.Equal(t, "8192m", pod.Containers[0].Env[envIndex].Value) From c157394ff83495712e47f2942882776c63fa46a7 Mon Sep 17 00:00:00 2001 From: Kinga Kowalska <120555574+kingakowalska1@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:22:37 +0100 Subject: [PATCH 05/37] BUG-836823 - Fixed typo "Zero-downtime" to "zero-downtime" (#664) --- docs/upgrading-pega-deployment-zero-downtime.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/upgrading-pega-deployment-zero-downtime.md b/docs/upgrading-pega-deployment-zero-downtime.md index a4d9326af..1b496d3b3 100644 --- a/docs/upgrading-pega-deployment-zero-downtime.md +++ b/docs/upgrading-pega-deployment-zero-downtime.md @@ -113,7 +113,7 @@ To complete an upgrade with zero downtime, configure the following settings in - In the installer section of the Helm chart, update the following: - Specify `installer.installerMountVolumeClaimName` persistent Volume Claim name. This is a client-managed PVC for mounting upgrade artifacts. - - Specify `installer.upgradeType: "Zero-downtime"` to use the zero-downtime upgrade process. + - Specify `installer.upgradeType: "zero-downtime"` to use the zero-downtime upgrade process. - Specify `installer.targetRulesSchema: ""` and `installer.targetDataSchema: ""` for the new target and data schema name that the process creates in your existing database for the upgrade process. - Specify `installer.upgrade.automaticResumeEnabled` to support resuming from point of failure @@ -202,4 +202,4 @@ In this document, you specify that the Helm chart always “deploys” by using - `action.execute: upgrade-deploy` - `installer.upgrade.upgradeType: custom` - `installer.upgrade.upgradeSteps: disable_cluster_upgrade` to run disable_cluster_upgrade -- Resume the upgrade process by using the `helm upgrade release --namespace mypega` command. For more information, see - [Upgrading your Pega Platform deployment using the command line](https://github.com/pegasystems/pega-helm-charts/blob/master/docs/upgrading-pega-deployment-zero-downtime.md#upgrading-your-pega-platform-deployment-using-the-command-line). \ No newline at end of file +- Resume the upgrade process by using the `helm upgrade release --namespace mypega` command. For more information, see - [Upgrading your Pega Platform deployment using the command line](https://github.com/pegasystems/pega-helm-charts/blob/master/docs/upgrading-pega-deployment-zero-downtime.md#upgrading-your-pega-platform-deployment-using-the-command-line). From 25ddd3c1f093871598f69c7135ee4b334bd91650 Mon Sep 17 00:00:00 2001 From: pega-Abhinav <110885740+pega-Abhinav@users.noreply.github.com> Date: Fri, 17 Nov 2023 11:52:00 +0530 Subject: [PATCH 06/37] BUG-830220 : Removed security/urlaccessmode configuration as it is no longer applicable (#666) --- charts/pega/Ephemeral-web-tier-values.yaml | 1 - charts/pega/config/deploy/prconfig.xml | 1 - terratest/src/test/pega/data/expectedInstallDeployPrconfig.xml | 1 - 3 files changed, 3 deletions(-) diff --git a/charts/pega/Ephemeral-web-tier-values.yaml b/charts/pega/Ephemeral-web-tier-values.yaml index f7159fbc1..4e5d9c99f 100644 --- a/charts/pega/Ephemeral-web-tier-values.yaml +++ b/charts/pega/Ephemeral-web-tier-values.yaml @@ -94,7 +94,6 @@ global: - diff --git a/charts/pega/config/deploy/prconfig.xml b/charts/pega/config/deploy/prconfig.xml index a72ea2f01..96e9c2e78 100644 --- a/charts/pega/config/deploy/prconfig.xml +++ b/charts/pega/config/deploy/prconfig.xml @@ -6,7 +6,6 @@ - diff --git a/terratest/src/test/pega/data/expectedInstallDeployPrconfig.xml b/terratest/src/test/pega/data/expectedInstallDeployPrconfig.xml index a72ea2f01..96e9c2e78 100644 --- a/terratest/src/test/pega/data/expectedInstallDeployPrconfig.xml +++ b/terratest/src/test/pega/data/expectedInstallDeployPrconfig.xml @@ -6,7 +6,6 @@ - From d2bdebfbb69fb6337410186c69b43b55a632c9e4 Mon Sep 17 00:00:00 2001 From: Kinga Kowalska <120555574+kingakowalska1@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:18:38 +0100 Subject: [PATCH 07/37] [BUG-830515] Fixed link for Node types for VM-based and containerized deployments (#644) --- charts/pega/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/pega/README.md b/charts/pega/README.md index e48632596..7e4355b33 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -270,7 +270,7 @@ Node classification is the process of separating nodes by purpose, predefining t Specify the list of Pega node types for this deployment. For more information about valid node types, see the Pega Community article on [Node Classification]. -[Node types for client-managed cloud environments](https://community.pega.com/knowledgebase/articles/performance/node-classification) +[Node types for VM-based and containerized deployments](https://docs.pega.com/bundle/platform-88/page/platform/system-administration/node-types-on-premises.html) Example: From 88cca869773c91334b2d9725b7647e4862ed0768 Mon Sep 17 00:00:00 2001 From: Davis Walsh Date: Tue, 21 Nov 2023 17:55:50 -0500 Subject: [PATCH 08/37] Fix level for usage metric logging (#667) * Fix level for usage metric logging * update test --------- Co-authored-by: Adam Talbot --- charts/pega/config/deploy/prlog4j2.xml | 2 +- terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/pega/config/deploy/prlog4j2.xml b/charts/pega/config/deploy/prlog4j2.xml index 88d7fc3e4..860959a77 100644 --- a/charts/pega/config/deploy/prlog4j2.xml +++ b/charts/pega/config/deploy/prlog4j2.xml @@ -160,7 +160,7 @@ - + diff --git a/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml b/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml index 3b4bb30fc..c1910278b 100644 --- a/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml +++ b/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml @@ -160,7 +160,7 @@ - + From 9ccd6b510493e83d7a33c56cfee2d886491c03b0 Mon Sep 17 00:00:00 2001 From: anilkumargedela <77138263+anilkumargedela@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:15:28 +0530 Subject: [PATCH 09/37] SRS: Added truststore password input for TLS connection b/w SRS and ES (#669) * [SRS] Added truststore password input for TLS connection b/w SRS and ES --- charts/backingservices/charts/srs/README.md | 6 +++++- .../charts/srs/templates/srsservice_deployment.yaml | 2 ++ charts/backingservices/values.yaml | 4 +++- terratest/src/test/backingservices/srs-deployment_test.go | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index feffbb959..278d53fe2 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -76,6 +76,8 @@ make external-es-secrets NAMESPACE=pegabackingservices ELASTICSEARCH_VERSION=7.1 | Configuration | Usage | |-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `tls` | Set to `true` to enable the SRS service to authenticate to your organization's available Elasticsearch service. | +| `certificateName` | Enter the tls certificate name. Default certificate name will be "elastic-certificates.p12" if not used. | +| `certificatePassword` | Enter the tls certificate password if any. Default value will be empty if not used. | | `esCredentials.username` | Enter the username for your available Elasticsearch service. This username value must match the values you set in the connection info section of esCredentials. | | `esCredentials.password` | Enter the required password for your available Elasticsearch service. This password value must match the values you set in the connection info section of esCredentials. | | `srsStorage.provisionInternalESCluster` |
  • Set to false to disable this parameter and connect to your available Elasticsearch service from the SRS cluster. Disabling this setting requires you to provide connectivity details to your organization's external Elasticsearch service along with an appropriate TLS certificate with which you authenticate with the service. To pass the required certificate to the cluster using a secrets file, run the command, `$ make external-es-secrets NAMESPACE= ELASTICSEARCH_VERSION= PATH_TO_CERTIFICATE=`.
  • where NAMESPACE references your deployment namespace of the SRS cluster, `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use, and `PATH_TO_CERTIFICATE` points to the location where you copied the required certificates on your location machine.
  • Use the following Make command to update the SRS and External Elasticsearch certificates: `$ make update-external-es-secrets NAMESPACE= PATH_TO_CERTIFICATE=`.
| @@ -140,8 +142,10 @@ srs: # Set srs.srsStorage.tls.enabled: true to enable the use of TLS-based authentication to your Elasticsearch service whether is it running as an internalized or externalized service in your SRS cluster. tls: enabled: false - # To specify a certificate used to authenticate an external Elasticsearch service (with tls.enabled: true and srsStorage.provisionInternalESCluster: false), uncomment the following line to specify the TLS certificate name for your Elasticsearch service. + # To specify a certificate used to authenticate an external Elasticsearch service (with tls.enabled: true and srsStorage.provisionInternalESCluster: false), uncomment the following lines to specify the TLS certificate name with password for your Elasticsearch service. + # Default certificatePassword value will be empty if not used. # certificateName: "Certificate_Name" + # certificatePassword: "password" # Set srs.srsStorage.basicAuthentication.enabled: true to enable the use of basic authentication to your Elasticsearch service whether is it running as an internalized or externalized service in your SRS cluster. basicAuthentication: enabled: true diff --git a/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml b/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml index acd6b06f0..feaa8bd7b 100644 --- a/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml +++ b/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml @@ -77,6 +77,8 @@ spec: key: password - name: PATH_TO_TRUSTSTORE value: "/usr/share/{{ .Values.srsStorage.certificateName | default "elastic-certificates.p12"}}" + - name: PATH_TO_KEYSTORE + value: "{{ .Values.srsStorage.certificatePassword | default ""}}" {{- end}} - name: APPLICATION_HOST value: "0.0.0.0" diff --git a/charts/backingservices/values.yaml b/charts/backingservices/values.yaml index b4a5cce18..0563e8bea 100644 --- a/charts/backingservices/values.yaml +++ b/charts/backingservices/values.yaml @@ -53,8 +53,10 @@ srs: tls: enabled: false # To specify a certificate used to authenticate an external Elasticsearch service (with tls.enabled: true and srsStorage.provisionInternalESCluster: false), - # uncomment the following line to specify the TLS certificate name for your Elasticsearch service. + # uncomment the following lines to specify the TLS certificate name with password for your Elasticsearch service. + # Default certificatePassword value will be empty if not used. # certificateName: "Certificate_Name" + # certificatePassword: "password" # Set srs.srsStorage.basicAuthentication.enabled: true to enable the use of basic authentication to your Elasticsearch service # whether is it running as an internalized or externalized service in your SRS cluster. basicAuthentication: diff --git a/terratest/src/test/backingservices/srs-deployment_test.go b/terratest/src/test/backingservices/srs-deployment_test.go index dc1cd943b..ae7cdadf0 100644 --- a/terratest/src/test/backingservices/srs-deployment_test.go +++ b/terratest/src/test/backingservices/srs-deployment_test.go @@ -206,6 +206,9 @@ func VerifyDeployment(t *testing.T, pod *k8score.PodSpec, expectedSpec srsDeploy require.Equal(t, "PATH_TO_TRUSTSTORE", pod.Containers[0].Env[envIndex].Name) require.Equal(t, "/usr/share/elastic-certificates.p12", pod.Containers[0].Env[envIndex].Value) envIndex++ + require.Equal(t, "PATH_TO_KEYSTORE", pod.Containers[0].Env[envIndex].Name) + require.Equal(t, "", pod.Containers[0].Env[envIndex].Value) + envIndex++ } require.Equal(t, "APPLICATION_HOST", pod.Containers[0].Env[envIndex].Name) require.Equal(t, "0.0.0.0", pod.Containers[0].Env[envIndex].Value) From 1dc316c73a1f899a955aca8ef2434e64db0948a0 Mon Sep 17 00:00:00 2001 From: akshithac-21 <59637571+akshithac-21@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:35:48 +0530 Subject: [PATCH 10/37] support for compressed configuration (#672) --- charts/pega/README.md | 17 +++++++++++++++++ .../pega/templates/pega-environment-config.yaml | 6 ++++++ charts/pega/values.yaml | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/charts/pega/README.md b/charts/pega/README.md index 7e4355b33..f56f6c8d5 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -652,6 +652,23 @@ tier: webXML: |- ... ``` +### Pega compressed configuration files + +To use [Pega configuration files](https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#pega-configuration-files) in compressed format when deploying Pega Platform, replace each file with its compressed format file by completing the following steps: + +1) Compress each configuration file using the following command in your local terminal: +``` +- cat "" | gzip -c | base64 +``` +Example for a prconfig.xml file: +``` +cat "pega-helm-charts/charts/pega/config/deploy/prconfig.xml" | gzip -c | base64 +``` +2) Provide the file content with the output of the command for each file executed. +3) Set the `compressedConfigurations` in values.yaml to `true`, as in the following example: +```yaml + compressedConfigurations: true +``` ### Pega diagnostic user diff --git a/charts/pega/templates/pega-environment-config.yaml b/charts/pega/templates/pega-environment-config.yaml index 44b2521c1..04e2e9482 100644 --- a/charts/pega/templates/pega-environment-config.yaml +++ b/charts/pega/templates/pega-environment-config.yaml @@ -43,6 +43,12 @@ data: JDBC_TIMEOUT_PROPERTIES_RO: {{ .Values.global.jdbc.readerConnectionTimeoutProperties }} {{- else }} JDBC_TIMEOUT_PROPERTIES_RO: "" +{{- end }} + # compression flag to decompress the config files of Pega Installation. +{{- if .Values.global.compressedConfigurations }} + IS_PEGA_CONFIG_COMPRESSED: "{{ .Values.global.compressedConfigurations }}" +{{- else }} + IS_PEGA_CONFIG_COMPRESSED: "false" {{- end }} # Rules schema of the Pega installation {{ if (eq (include "performUpgradeAndDeployment" .) "true") }} diff --git a/charts/pega/values.yaml b/charts/pega/values.yaml index e375fc52a..83c9cdf5b 100644 --- a/charts/pega/values.yaml +++ b/charts/pega/values.yaml @@ -121,6 +121,10 @@ global: serviceHost: "API_SERVICE_ADDRESS" httpsServicePort: "SERVICE_PORT_HTTPS" + # Set the `compressedConfigurations` parameter to `true` when the configuration files under charts/pega/config/deploy are in compressed format. + # For more information, see the “Pega compressed configuration files” section in the Pega Helm chart documentation. + compressedConfigurations: false + # Specify the Pega tiers to deploy tier: - name: "web" From 241bbb92e4078a55bf9e670269af22ec599b81d2 Mon Sep 17 00:00:00 2001 From: saran-teja-7 <126812400+saran-teja-7@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:48:00 +0530 Subject: [PATCH 11/37] US-583096 : Updated SRS Docker Image version from 1.25.3 to 1.28.0 (#675) --- charts/backingservices/charts/srs/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index 278d53fe2..90b0f0c61 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -18,19 +18,19 @@ The service deployment provisions runtime service pods along with a dependency o | Pega Infinity version | SRS version | Elasticsearch version | Description | |-----------------------|-------------|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | < 8.6 | NA | NA | SRS can be used with Pega Infinity 8.6 and later | -| \>= 8.6 | 1.25.3 | 7.10.2, 7.16.3, and 7.17.9 | While SRS Docker images are certified against Elasticsearch versions 7.10.2, 7.16.3 and 7.17.9, Pega recommends using Elasticsearch version 7.17.9. To stay current with Pega releases, use the latest available SRS image 1.25.3. +| \>= 8.6 | 1.28.0 | 7.10.2, 7.16.3, and 7.17.9 | While SRS Docker images are certified against Elasticsearch versions 7.10.2, 7.16.3 and 7.17.9, Pega recommends using Elasticsearch version 7.17.9. To stay current with Pega releases, use the latest available SRS image 1.28.0. **Note**: **If your deployment uses the internally-provisioned Elasticsearch:** To migrate to Elasticsearch version 7.17.9 from the Elasticsearch version 7.10.2 or 7.16.3 use the process that applies to your deployment: -* Update the SRS Docker image version to use v1.25.3, which supports both Elasticsearch versions 7.10.x and 7.16.x. +* Update the SRS Docker image version to use v1.28.0, which supports both Elasticsearch versions 7.10.x and 7.16.x. * Update the Elasticsearch `dependencies.version` parameter in the [requirement.yaml](../../requirements.yaml) to 7.17.3. * Update Elasticsearch to 7.17.9. **If your deployment connects to an externally-managed Elasticsearch service:** To migrate to Elasticsearch version 7.17.9 from the Elasticsearch version 7.10.2 or 7.16.3 use the process that applies to your deployment: -* Update the SRS Docker image version to use v1.25.3, which supports both Elasticsearch versions 7.10.x and 7.16.x. +* Update the SRS Docker image version to use v1.28.0, which supports both Elasticsearch versions 7.10.x and 7.16.x. * Complete the version upgrade to 7.17.9. Refer to Elasticsearch version 7.17 documentation. For example, see [Upgrade Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setup-upgrade.html). ### SRS runtime configuration From f453712e6bbe7d3b73291e49f643021383262091 Mon Sep 17 00:00:00 2001 From: Kinga Kowalska <120555574+kingakowalska1@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:04:21 +0100 Subject: [PATCH 12/37] BUG-822023 - Update readme to reflect current image rebuild policy (#678) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c12efecc3..7033631d5 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,8 @@ Digest: Status: Downloaded pega-docker.downloads.pega.com/platform/pega: ``` +All Docker images for Pega Platform releases that are in Standard Support undergo a nightly rebuild that applies the latest available updates and patches to all third-party components. To take advantage of these updates, you must redeploy your Pega Platform with the latest available images. Pega does not guarantee nightly rebuilds for Pega Platform releases in Extended Support and stops rebuilding images for Pega Platform releases that are out of Extended Support. + For details about downloading and then pushing Docker images to your repository for your deployment, see [Using Pega-provided Docker images](https://docs.pega.com/bundle/platform-88/page/platform/deployment/client-managed-cloud/pega-docker-images-manage.html). From Helm chart versions `2.2.0` and above, update your Pega Platform version to the latest patch version. From abe31ba087a554fb4d628041075095383887bb9f Mon Sep 17 00:00:00 2001 From: Kinga Kowalska <120555574+kingakowalska1@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:02:50 +0100 Subject: [PATCH 13/37] =?UTF-8?q?BUG-801156=20-=20Clarified=20messaging=20?= =?UTF-8?q?for=20Makefile=20commands=20for=20SRS=20deploy=E2=80=A6=20(#677?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * BUG-801156 - Clarified messaging for Makefile commands for SRS deployment * [BUG-801156] Updated cluster to service --- charts/backingservices/charts/srs/README.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index 90b0f0c61..c8602b67a 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -43,8 +43,8 @@ You may enable the component of [Elasticsearch](https://github.com/helm/charts/t Note: Pega does **not** actively update the elasticsearch dependency in `requirements.yaml`. To leverage SRS, you must do one of the following: -* To use the internally-provided Elasticsearch service in the SRS cluster, use the default `srs.enabled.true` parameter and set the Elasticsearch version by updating the `elasticsearch.imageTag` parameter in the [values.yaml](./values.yaml) to match the `dependencies.version` parameter in the [requirements.yaml](../../requirements.yaml). -* To use an externally-provided Elasticsearch service with SRS, use the default `srs.enabled.true` parameter, update the `srs.srsStorage.provisionInternalESCluster` parameter in the [values.yaml](./values.yaml) to `false` and then provide connection details as documented below. +* To use the internally-provided Elasticsearch service in the SRS cluster, use the default `srs.enabled.true` parameter and set the Elasticsearch version by updating the `elasticsearch.imageTag` parameter in the [values.yaml](./values.yaml) to match the `dependencies.version` parameter in the [requirements.yaml](../../requirements.yaml). This method streamlines the deployment process for development and testing environments, but it is not suitable for production environments, which require a fully external Elasticsearch cluster. Additionally, even though you deploy SRS and Elasticsearch together, Pega does not license the Elasticsearch cluster deployed using this method and does not maintain it as part of the Pega Platform support. +* To use an externally-provided Elasticsearch service with SRS, use the default `srs.enabled.true` parameter, update the `srs.srsStorage.provisionInternalESCluster` parameter in the [values.yaml](./values.yaml) to `false` and then provide connection details as documented below. This is the recommended method and is suitable for production environments. ### Deploying SRS with Pega-provided busybox images To deploy Pega Platform with the SRS backing service, the SRS helm chart requires the use of the busybox image. For clients who want to pull this image from a registry other than Docker Hub, they must tag and push their image to another registry, and then pull it by specifying `busybox.image` and `busybox.imagePullPolicy`. @@ -61,17 +61,15 @@ To deploy Pega Platform with the SRS backing service, the SRS helm chart require | `k8sProvider` | Specify your Kubernetes provider name. Supported values are [`eks`, `aks`, `minikube`, `gke`, `openshift`, `pks`].. ### Enabling security between SRS and Elasticsearch -To configure a secure connection between the SRS cluster and Elasticsearch, add the following the settings in your backingservices configuration file to reflect your organization's connectivity setup. +Enabling a secure connection between SRS and your Elasticsearch service depends on the method you chose to deploy the Elasticsearch cluster. +To configure a secure connection between the SRS cluster and internally provisioned Elasticsearch, configure the following parameters. | Configuration | Usage | |------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `tls` | Set to `true` to enable the SRS service to authenticate to your organization's available Elasticsearch service. | -| `srsStorage.provisionInternalESCluster` |
  • Set to `true` to enable this parameter to provide an internally managed and secured Elasticsearch cluster to be used with the SRS cluster. After you specify an Elasticsearch version in the SRS Helm chart and save the file, run `$ make es-prerequisite NAMESPACE= ELASTICSEARCH_VERSION=`.
  • Where `NAMESPACE` references your deployment namespace of the SRS cluster and `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use in [values.yaml](../../values.yaml) and [requirements.yaml](../../requirements.yaml).
| +| `srsStorage.provisionInternalESCluster` |
  1. Set the `srsStorage.provisionInternalESCluster` parameter to `true` to provide an internally managed and secured Elasticsearch cluster.
  2. In the [requirements.yaml](../../requirements.yaml) file, set the `dependencies.version` parameter to the same version you configured for the `elasticsearch.imageTag` version in the Backing Services Helm chart [values.yaml](../../values.yaml) file.
  3. From the Backing Services Helm chart directory in your environment, run the following command to create your Elasticsearch certificates and pass them to secrets:

    `$ make es-prerequisite NAMESPACE= ELASTICSEARCH_VERSION=`

    Where `NAMESPACE` references your deployment namespace of the SRS cluster and `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use in [values.yaml](../../values.yaml) and [requirements.yaml](../../requirements.yaml).

| -To connect to external elasticsearch below configuration needs to be made. -Certificates used by external elasticsearch need to be placed in an accessible location for make command to use. -eg: If certs are placed under /home/certs. Make command will look like this: -make external-es-secrets NAMESPACE=pegabackingservices ELASTICSEARCH_VERSION=7.10.2 PATH_TO_CERTIFICATE=/home/certs/truststore.jks +To configure a secure connection between SRS and an external Elasticsearch cluster, configure the following parameters. | Configuration | Usage | |-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -80,7 +78,7 @@ make external-es-secrets NAMESPACE=pegabackingservices ELASTICSEARCH_VERSION=7.1 | `certificatePassword` | Enter the tls certificate password if any. Default value will be empty if not used. | | `esCredentials.username` | Enter the username for your available Elasticsearch service. This username value must match the values you set in the connection info section of esCredentials. | | `esCredentials.password` | Enter the required password for your available Elasticsearch service. This password value must match the values you set in the connection info section of esCredentials. | -| `srsStorage.provisionInternalESCluster` |
  • Set to false to disable this parameter and connect to your available Elasticsearch service from the SRS cluster. Disabling this setting requires you to provide connectivity details to your organization's external Elasticsearch service along with an appropriate TLS certificate with which you authenticate with the service. To pass the required certificate to the cluster using a secrets file, run the command, `$ make external-es-secrets NAMESPACE= ELASTICSEARCH_VERSION= PATH_TO_CERTIFICATE=`.
  • where NAMESPACE references your deployment namespace of the SRS cluster, `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use, and `PATH_TO_CERTIFICATE` points to the location where you copied the required certificates on your location machine.
  • Use the following Make command to update the SRS and External Elasticsearch certificates: `$ make update-external-es-secrets NAMESPACE= PATH_TO_CERTIFICATE=`.
| +| `srsStorage.provisionInternalESCluster` |
  1. Set the `srsStorage.provisionInternalESCluster` parameter to `false` to disable the internally provisioned Elasticsearch cluster and connect to your available external Elasticsearch service.
  2. To secure the connection between SRS and your external Elasticsearch service, you must provide the appropriate TLS certificates in an accessible location, for example, /home/certs.
  3. To pass the required certificates to the cluster using a secrets file, run the following command:

    `$ make external-es-secrets NAMESPACE= ELASTICSEARCH_VERSION= PATH_TO_CERTIFICATE=`

    Where NAMESPACE references your deployment namespace of the SRS cluster, `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use, and `PATH_TO_CERTIFICATE` points to the location where you copied the required certificates on your location machine, for example:

    `$ make external-es-secrets NAMESPACE=pegabackingservices ELASTICSEARCH_VERSION=7.10.2 PATH_TO_CERTIFICATE=/home/certs/truststore.jks`

  4. To update the SRS and External Elasticsearch certificates, use the following command:

    `$ make update-external-es-secrets NAMESPACE= PATH_TO_CERTIFICATE=`

| | `domain` | Enter the DNS entry associated with your external Elasticsearch service. | Note: Only .p12 and .jks certificates are supported. @@ -180,4 +178,4 @@ To support SRS on Kubernetes version >=1.25 you need to use Elasticsearch server ``` 5. Verify that the Elasticsearch pods status is Running. 6. Restart the old SRS pods and verify that the status of the new pods is Running. -7. Verify all pods are running and working as expected. \ No newline at end of file +7. Verify all pods are running and working as expected. From 6fc9934bc80d655d06343279f4c6503262db793b Mon Sep 17 00:00:00 2001 From: Kinga Kowalska <120555574+kingakowalska1@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:21:25 +0100 Subject: [PATCH 14/37] BUG-817356 - Clarified step for configuring External Secrets Operator (#679) BUG-817356 - Helm Charts issue #603 - ESO documentation misleading --- charts/pega/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/pega/README.md b/charts/pega/README.md index f56f6c8d5..37982df11 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -102,7 +102,7 @@ To support this option, 2) Copy both files into the pega-helm-charts/charts/pega/templates directory of your local Helm repository. 3) Update your local Helm repository to the latest version using the command: - helm repo update pega https://pegasystems.github.io/pega-helm-charts -4) Update your values.yaml file to refer to the external secret manager for DB password. +4) Update the `external_secret_name` parameter in the values.yaml file to refer to the `spec.target.name` defined in the External Secret file you created in step 1. Update the parameter for each section where you want to use the External Secrets Operator. • Pass secrets directly to your deployment using your organization's recommend practices. Pega supports the providers listed under the [Provider tab]( https://external-secrets.io/v0.8.1) as long as your implementation meets the documented guidelines for a given provider. From a71194ec1563ef829d8467ef6f3ee6d8e825bc37 Mon Sep 17 00:00:00 2001 From: vnihal72 <79415342+vnihal72@users.noreply.github.com> Date: Tue, 19 Dec 2023 18:12:42 +0530 Subject: [PATCH 15/37] BUG-808734 : HZ GC setting updated (#684) * BUG-808734 : HZ GC setting updated Co-authored-by: vermn1 --- charts/pega/charts/hazelcast/values.yaml | 3 ++- .../test/pega/clustering-service-environment-config_test.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/charts/pega/charts/hazelcast/values.yaml b/charts/pega/charts/hazelcast/values.yaml index 56079d303..f7d7cad8e 100644 --- a/charts/pega/charts/hazelcast/values.yaml +++ b/charts/pega/charts/hazelcast/values.yaml @@ -39,7 +39,8 @@ client: # Server side settings for Hazelcast server: java_opts: "-XX:MaxRAMPercentage=80.0 -XX:InitialRAMPercentage=80.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof - -XX:+UseParallelGC -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m -XshowSettings:vm" + -XX:+UseG1GC -XX:NewRatio=3 -XshowSettings:vm -XX:InitiatingHeapOccupancyPercent=45 + -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m" jmx_enabled: "true" health_monitoring_level: "OFF" operation_generic_thread_count: "" diff --git a/terratest/src/test/pega/clustering-service-environment-config_test.go b/terratest/src/test/pega/clustering-service-environment-config_test.go index cca1a2c0f..2468a358e 100644 --- a/terratest/src/test/pega/clustering-service-environment-config_test.go +++ b/terratest/src/test/pega/clustering-service-environment-config_test.go @@ -49,7 +49,7 @@ func VerifyClusteringServiceEnvironmentConfig(t *testing.T, yamlContent string, UnmarshalK8SYaml(t, statefulInfo, &clusteringServiceEnvConfigMap) clusteringServiceEnvConfigData := clusteringServiceEnvConfigMap.Data require.Equal(t, clusteringServiceEnvConfigData["NAMESPACE"], "default") - require.Equal(t, clusteringServiceEnvConfigData["JAVA_OPTS"], "-XX:MaxRAMPercentage=80.0 -XX:InitialRAMPercentage=80.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof -XX:+UseParallelGC -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m -XshowSettings:vm") + require.Equal(t, clusteringServiceEnvConfigData["JAVA_OPTS"], "-XX:MaxRAMPercentage=80.0 -XX:InitialRAMPercentage=80.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/hazelcast/logs/heapdump.hprof -XX:+UseG1GC -XX:NewRatio=3 -XshowSettings:vm -XX:InitiatingHeapOccupancyPercent=45 -Xlog:gc*,gc+phases=debug:file=/opt/hazelcast/logs/gc.log:time,pid,tags:filecount=5,filesize=3m") require.Equal(t, clusteringServiceEnvConfigData["SERVICE_NAME"], "clusteringservice-service") require.Equal(t, clusteringServiceEnvConfigData["MIN_CLUSTER_SIZE"], "3") require.Equal(t, clusteringServiceEnvConfigData["JMX_ENABLED"], "true") From b0518b117aa874e73300898dd94ff07fc5e37e7f Mon Sep 17 00:00:00 2001 From: Heshma Date: Tue, 19 Dec 2023 17:22:55 -0500 Subject: [PATCH 16/37] Installer subchart to pick up custom artifactory credentials (#687) * Adding custom artifactory creds in installer subchart * added test --------- Co-authored-by: degah --- .../installer/templates/_pega-installer-job.tpl | 3 +++ terratest/src/test/pega/pega-installer-job_test.go | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/charts/pega/charts/installer/templates/_pega-installer-job.tpl b/charts/pega/charts/installer/templates/_pega-installer-job.tpl index 5e15023f7..683a6ec82 100644 --- a/charts/pega/charts/installer/templates/_pega-installer-job.tpl +++ b/charts/pega/charts/installer/templates/_pega-installer-job.tpl @@ -63,6 +63,9 @@ spec: {{- $d := dict "deploySecret" "deployDBSecret" "deployNonExtsecret" "deployNonExtDBSecret" "extSecretName" .root.Values.global.jdbc.external_secret_name "nonExtSecretName" "pega-db-secret-name" "context" .root -}} {{ include "secretResolver" $d | indent 10}} + {{- $artifactoryDict := dict "deploySecret" "deployArtifactorySecret" "deployNonExtsecret" "deployNonExtArtifactorySecret" "extSecretName" .root.Values.global.customArtifactory.authentication.external_secret_name "nonExtSecretName" "pega-custom-artifactory-secret-name" "context" .root -}} + {{ include "secretResolver" $artifactoryDict | indent 10}} + # Fix it, Below peace of code always uses secret created from hz username & password. It cannot resolve hz external secret due to helm sub chart limitations. Modify it once hazelcast deployment is isolated. {{- if ( eq .root.Values.upgrade.isHazelcastClientServer "true" ) }} - secret: diff --git a/terratest/src/test/pega/pega-installer-job_test.go b/terratest/src/test/pega/pega-installer-job_test.go index 73dd54ff7..0846188d3 100644 --- a/terratest/src/test/pega/pega-installer-job_test.go +++ b/terratest/src/test/pega/pega-installer-job_test.go @@ -19,6 +19,7 @@ type pegaDbJob struct { } var volDefaultMode int32 = 420 +var customArtifactorySecret = "artifactory_secret" var volDefaultModePointer = &volDefaultMode func TestPegaInstallerJob(t *testing.T) { @@ -36,11 +37,12 @@ func TestPegaInstallerJob(t *testing.T) { for _, pullPolicy := range imagePullPolicy { var options = &helm.Options{ SetValues: map[string]string{ - "global.deployment.name": depName, - "global.provider": vendor, - "global.actions.execute": operation, - "installer.imagePullPolicy": pullPolicy, - "installer.upgrade.upgradeType": "zero-downtime", + "global.deployment.name": depName, + "global.provider": vendor, + "global.actions.execute": operation, + "global.customArtifactory.authentication.external_secret_name": customArtifactorySecret, + "installer.imagePullPolicy": pullPolicy, + "installer.upgrade.upgradeType": "zero-downtime", }, } yamlContent := RenderTemplate(t, options, helmChartPath, []string{"charts/installer/templates/pega-installer-job.yaml"}) @@ -114,6 +116,7 @@ func assertJob(t *testing.T, jobYaml string, expectedJob pegaDbJob, options *hel require.Equal(t, jobSpec.Volumes[0].Name, "pega-installer-credentials-volume") require.Equal(t, jobSpec.Volumes[0].VolumeSource.Projected.Sources[0].Secret.Name, getObjName(options, "-db-secret")) + require.Equal(t, jobSpec.Volumes[0].VolumeSource.Projected.Sources[1].Secret.Name, customArtifactorySecret) require.Equal(t, jobSpec.Volumes[0].VolumeSource.Projected.DefaultMode, volDefaultModePointer) require.Equal(t, jobSpec.Volumes[1].Name, "pega-volume-installer") if jobSpec.Volumes[1].VolumeSource.ConfigMap.LocalObjectReference.Name == "pega-install-config" { From 74420286b4f3e89fcc4d3db7db14f0b3e8bea591 Mon Sep 17 00:00:00 2001 From: Ryan Feeney Date: Thu, 21 Dec 2023 09:16:55 -0500 Subject: [PATCH 17/37] Add diagram for eks deployment (#552) * Add diagram for eks deployment * Add hazelcast to diagram * Removed visibility markings * Updated diagram. Added image description --------- Co-authored-by: Kishor Kumar Vasantala Co-authored-by: MadhuriArugula --- docs/Deploying-Pega-on-EKS.md | 4 ++++ docs/media/deploying-pega-on-eks.png | Bin 0 -> 370087 bytes 2 files changed, 4 insertions(+) create mode 100644 docs/media/deploying-pega-on-eks.png diff --git a/docs/Deploying-Pega-on-EKS.md b/docs/Deploying-Pega-on-EKS.md index 72092a046..7a7978971 100644 --- a/docs/Deploying-Pega-on-EKS.md +++ b/docs/Deploying-Pega-on-EKS.md @@ -8,6 +8,10 @@ Pega helps enterprises and agencies quickly build business apps that deliver the Create a deployment of Pega Platform on which you can implement a scalable Pega application in a EKS cluster. You can use this deployment for a Pega Platform development environment. By completing these procedures, you deploy Pega Platform on a EKS cluster with a Amazon RDS database instance and two clustered virtual machines (VMs). +*The following diagram shows how Pega Infinity 8.7 can be deployed on AWS with EKS* +![Overview of EKS Pega Deployment](media/deploying-pega-on-eks.png) + + ## Deployment process overview Use Kubernetes tools and the customized orchestration tools and Docker images to orchestrate a deployment in a EKS cluster that you create for the deployment: diff --git a/docs/media/deploying-pega-on-eks.png b/docs/media/deploying-pega-on-eks.png new file mode 100644 index 0000000000000000000000000000000000000000..1a2424e9294828d41553dd9a64d73c6025050f40 GIT binary patch literal 370087 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 z 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 z zEK9HZq+vzPPJ%9>L40&O)>~#M3%@Q(q&AamOk07~oY(;Vn-GMl`R>H?tl)d$*S&Jm zqEA2dKPzdZNeF>O6I(;M##oVFyJvc~8lA0e9w}MCNez*}A4Kpb1V|vYUK|yWkWR_#!ksV=IJ85?!?pxp&m&MZweCH89Z>|nyzs^LY*8*@ zc%t)rw4MkL%Fv%KZ^O&{zU$^gll`Ztg127Cvf?9cAl8=JOced0SbXR<*05d7x_$?V z8x+X53^P9hPdpY_C^=~H^+wr?$~F%J+~vi0Z#R5|(=*J9+_oqWGOivvbS?CV(j+$!Dn2E`zN{szNk`@^B1ErGur+Xon ztA?Dpb4}{LOkZ(y>DP{Bd7|_nCvNdH4#u`hx;j1ff4Dkope_r2c~f z|DZr9Bm92}1%4O*n`bkW2il# z*u%S2r$_42ws;b#GJLiEwYOkw1+tM$RF^aaWD=4wN2guR&D9+wSX)L^Og&g?BmqdG zCO8^JDC8R|YMxT_j^#Q2?!Nt<3&pmHB|I1nc)%$(a6Ob~mbE^!fPo2m6G-KG_RD&?!zLsx`Ej0 zn*jP8UHE2QJ7g9z03+iaOcc;vwhqY-g}ms6Lv4lw&nl;ygbpFK3wunu&SwSBB)C4U--ij4;j9CT3Bh zyN)j;;p+!7oS!pg@KpdP8U$GEcM9i9C}YWKS@ z7!1#J5vFh1AMTCNIDutN_ug!cmwGxdVvComoiC8CW#uFo>YueAPV3H5D2kz)ZWb?? zg274dL69u!JscobGov@jQev}I#6=98=iiIX>fXE;X9GH_M~;IaH>$ z*CLyvB6Z=q5R(IP$P3GT^M33?)2{5x3)cOkj4Y8h*>lZJTU6DTLG=pLT*4_CyZ;tU z%rxL4zQe^{how9^m+QE9Y0l%P#cS__jDX%-Ijumu+#33Irm%D;8HBXM!cmuZdlIHTaSCDvd|?=@0$4Apo zEJ~VxPCx@|8ZO8k6CdqtybL*ZaCQ&j|>?9h9z9f{f^FSz_-mf(Hc+zO--68Cjff*e#PSVPMxk-JrFP>x=Nc{WiKKvKwDQ^G@7g`WJ#p z3}kWv3PeSqqxg5Kp%??Y0iYBPe^TII$;V)z4&6*31!;nSEVbVpB(j6xu&IE3!*4Ze z6&p4{FR5a@sVV*`{4H}zbv@XtM&Ekj|F&Fc6aTdtj^barNZhmfNuV>}yZ2lE+wv{Y2Xv4G8j9uZ|C5Blry?HaB-U*<`ESdO zJD{BKhXTbaajap;3b&xK1K^?ChC8TMoco7;Pziz-QilvB#qaO9^6G>eV6T5v{#RQ4 yN9BL3aeq|)w@&ttmtW~#R=LFg&%FGi;GOewR^PT?drblUot9IUMV~Uh@xK5TYE(}E literal 0 HcmV?d00001 From d44491cc9db61eaf7be43232a4043e30180c5fb9 Mon Sep 17 00:00:00 2001 From: arvasrikanth <47382360+arvasrikanth@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:45:39 +0530 Subject: [PATCH 18/37] BUG-835374: Updating expired default keystore and CA certificate (#689) * Updating default keystore and CA certificate as they are expired --------- Co-authored-by: Arva --- charts/pega/README.md | 2 +- charts/pega/config/certs/pegaca.crt | 30 ++++++++++++++-------- charts/pega/config/certs/pegakeystore.jks | Bin 2242 -> 2255 bytes 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/charts/pega/README.md b/charts/pega/README.md index 37982df11..3ac46d82a 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -1165,7 +1165,7 @@ Parameter | Description | Default value `service.tls.traefik.insecureSkipVerify` | Set to `true` to skip verifying the certificate; do this in cases where you do not need a valid root/CA certificate but want to encrypt load balancer traffic. Leave the setting to `false` to both verify the certificate and encrypt load balancer traffic. | `false` ##### Important Points to note -- By default, Pega provides a self-signed keystore and a custom root/CA certificate in Helm chart version `2.2.0`. To use the default keystore and CA certificate, leave the parameters service.tls.keystore, service.tls.keystorepassword and service.tls.cacertificate empty. +- By default, Pega provides a self-signed keystore and a custom root/CA certificate in Helm chart version `2.2.0`. To use the default keystore and CA certificate, leave the parameters service.tls.keystore, service.tls.keystorepassword and service.tls.cacertificate empty. The default keystore and CA certificate expire on 25/12/2025. - To enable SSL, you must either provide a keystore with a keystorepassword or certificate, certificatekey and cacertificate files in PEM format. If you do not provide either, the deployment implements SSL by passing a Pega-provided default self-signed keystore and a custom root/CA certificate to the Pega web nodes. - The CA certificate can be issued by any valid Certificate Authorities or you can also use a self-created CA certificate with proper chaining. - To avoid exposing your certificates, you can use external secrets to manage your certificates. Pega also supports specifying the certificate files using the certificate parameters in the Pega values.yaml. To pass the files using these parameters, you must encode the certificate files using base64 and then enter the string output into the appropriate certificate parameter. diff --git a/charts/pega/config/certs/pegaca.crt b/charts/pega/config/certs/pegaca.crt index 0d9fbf3f8..709ac99e2 100644 --- a/charts/pega/config/certs/pegaca.crt +++ b/charts/pega/config/certs/pegaca.crt @@ -1,13 +1,21 @@ -----BEGIN CERTIFICATE----- -MIIB+DCCAZ8CFG8/fDwY/1tqXeTTzOkWL1mZ2wO3MAoGCCqGSM49BAMCMH8xCzAJ -BgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlDYW1i -cmlkZ2UxGDAWBgNVBAoMD1BlZ2FzeXN0ZW1zIEluYzEZMBcGA1UECwwQQ2xvdWRF -bmdpbmVlcmluZzEPMA0GA1UEAwwGcGVnYWNhMB4XDTIyMDUyNDExMDYzM1oXDTIz -MDUyNDExMDYzM1owfzELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0 -dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEYMBYGA1UECgwPUGVnYXN5c3RlbXMgSW5j -MRkwFwYDVQQLDBBDbG91ZEVuZ2luZWVyaW5nMQ8wDQYDVQQDDAZwZWdhY2EwWTAT -BgcqhkjOPQIBBggqhkjOPQMBBwNCAASk58j/K3IzPUnsQxSrQ0LgstNaefjUneFa -ewnBu1m2mMIIy1yEq66cai/o+95w0rzeHoaAhklxN9p3l2GIHbTwMAoGCCqGSM49 -BAMCA0cAMEQCIGHZKwtq7j7Avnq+0XakpFM6HNTBqLDCsWaegh379hElAiApObu8 -eLrNeUHdLylqMQ4dG/jSz17ovhOwgBu9A72dog== +MIIDgTCCAmmgAwIBAgIEbZW6yjANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJJ +TjESMBAGA1UECBMJVGVsYW5nYW5hMRIwEAYDVQQHEwlIeWRlcmFiYWQxFDASBgNV +BAoTC1BlZ2FzeXN0ZW1zMQ0wCwYDVQQLEwRQZWdhMRUwEwYDVQQDEwxQZWdhIFN5 +c3RlbXMwHhcNMjMxMjI2MTIxMDE2WhcNMjUxMjI1MTIxMDE2WjBxMQswCQYDVQQG +EwJJTjESMBAGA1UECBMJVGVsYW5nYW5hMRIwEAYDVQQHEwlIeWRlcmFiYWQxFDAS +BgNVBAoTC1BlZ2FzeXN0ZW1zMQ0wCwYDVQQLEwRQZWdhMRUwEwYDVQQDEwxQZWdh +IFN5c3RlbXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsATXTQFvw +NQtJwHPZRiCCdniD+416heVzdPT5LKLzRouiFKoq9mu449nQAzYDtYhpHhlDmgMO +hICthhNCO2d0OWN3mJatrI9d2F8N0iJD5YH+MyaEdDZzGg/eOAVredrLxQ+jf0FY +CtKxfPdRepdz2QfVs6O0wMDGusEH0uY9GSDnJT85sdTbbALTq+AJJGZhV9cAu3BF +BLbx2RR4V5G9NjvkjaiZQFGrBOlvm7sRhhgDAWvZu4dMspeum/dDUkHu1nIjFuXx +Jsg9ERUvmQWD3Xocs1wSACW41IL+OkMZ5awKSUgxpktoIXm+TZW4+uKVndGn0RSo +TKktJuT+yD5FAgMBAAGjITAfMB0GA1UdDgQWBBRVJZ0CLMWYWSw7LuEGnLUTx3MN +CzANBgkqhkiG9w0BAQsFAAOCAQEAKWSg7en7tHfOFlN1Ae0cZk1DHW9y8OwFpmrM +zgGjkM03VZHPh9orF++evFKcF2EyBKK34xD5CNEUH+WUAxe+vf6+u0Z/6Ru3Zhhs +3POKnUFoWqzioBJOXlz1xmtbhvjT1waZd2Lg0a1yhsk2fRIYk/vpIUqbWtMrporE +nyUsR7NOeMrj5pQiu8SpX3OgtKhVhkdG46wS9SnkpPLOOGyEyQ8ou9j/gG97Mzpz +jH4dmMoYc4YDMw0aLFIDHoINqA9fHZznGLXnkO959r9cWGDqUZH/tSyYE5Qy5D7w +6fT429bmovOShexqCRrzLciDPqdg7X5/YWAXXuGJlM0JYO4giQ== -----END CERTIFICATE----- diff --git a/charts/pega/config/certs/pegakeystore.jks b/charts/pega/config/certs/pegakeystore.jks index 7245c730bd15f8d0b80bfc505ef566b1657ef613..91cc451cb0b71ed36efc8336f413d40f794bf23f 100644 GIT binary patch literal 2255 zcmc(g={ppP7sqE0(~MLf!F}<4@%cXI#d*HxJm(xP9xeg^0MN03zs2D0;Dobt@bo%1 zo@FsOgr1jQ z0j5c1-Rew|sod0=hu;>w@~@cYp8~ z>h?N6F`rJLcm>BjXHm`kt5aM`UdTIMKH!C1C)sk}46&?q&n+_sFGDP9Hk!;H`%^%W zVh|m+#?Q>ZMS!{c({F3K5Upz!O|t2;+N8+u$*te~j3^5Tq-3QPu|WZP<)X;y8!hpA zq@Z|tgYo{^7y}k^6ndV`#QQ+SS!}>ta0u(_9)|S@#fUeij1l7lawKFq2ARKRy+vbk zcvYGeMT=wBq$FL!CFiEA{UTo5G{W2;#yBMo4|EMn7;b7By=L*2^NQqQG9(cU^wbc}6a;|(qchh!k(U(Ops=e83BGg<&y5eFInXG?J&|+k2LEMuvDI4{s zPAupmadSr_dCxl|`XIhjfN73WTT!bW*9mZUlm~4`MJUC zJhs2`3(2J{A4;zauHju(^ddpASf=ih1;;P6Auv4e`)5}}-Ws`9Exk|^Hr$$Yw{_Np zY$?P=cN_XyvAf1#j*#@~tU9x3MNv-IhYD5o@;)ZbA@6_pb%clcuU?R}`hLhHEQfoQv0!ns4@USy z%gJGU$GTCq8bQ_YmHbE%5do?hjt zy~L}7yv*6DGG&qZ5rqH3W1VJgVOPM&i@XE>cJDSFH+4C(Hb|H-P6rM1HCvZ#zf-(n zm}MaFd333Y`pBOu_W{QaoGGKcZJ;9u-Nvr}I5j)g1(jeEW{f*mS*mw zi5xC0tKnFP*%MpOY3lEM=VROPx$m2$P`$|Z{Ay`bpz{Ic*B>Hq5L`HqVE=j@lU)|9 z3*n-r^K+W3C`%r&yF|9H?d486VL6iBp5t}%Hp6Q5Y}B03lm%7@yfo7dZ1Zbq)NW5X zZ$*8)T?4rr;$ofNC^8d7n{GKpk#wZu*blT8H~Q3QZJ8~hajVn-8F)DBb4ai8N@TG&H3mR ztLR2ave0SW+Tm-W`=uRbW2Gg}OU0sd$wgd`@4B!Y?VZD9{639PbJ+`MWdHyiiY9@H zXcFi?4GaQ;K#+%tRqbd5j8TfLL*7CFfp91Q?SX-#8DU^k2n+?faTCLaW;p={6yt3N zSDc#@&JFjEcM8R*<7@BWiL=GoW7yGbCv{9HxY6+)#{1&E93J8^2sHe}g`*%RE`|e* zIzce%^a%=>{J#p#&xMdzz{txhVdODrj1u-3FC62se&c`95(y~u?_iGK2ABk72B1km zCJ+e-1QY--^sC)nxd6XWj~~(!AbI-)??w5A&fvW^cBIqSwIb8m^Q3;cR89@`fR(`I zVfXpZXuJR;LxKv)sB0=tUdncaWJ+N{wAEK@M4ynx4DnDwEW}F*&%-=+3F_iI+|kUO z5vXp?)K~I&%h)doKXmHL+l;dM`j)DOQ+=~n&IrtjUR5snJmL!K&mU(Lam3vj1XR0g zLjGPIV)wZdTdSlp9hH-!W}FY1e?+ZjC3Ay;E<@E%^-GhAs9PGh)RzW4g*j(d#XeqP z<&aB(2Gjk{zO`fnh*o|k9bVQrGgH8HLkE+k=Pc-3XOLLAJDHf;o88Nvqn|4yHhuU} zRTBgT0)QEU=yPbk}5Hs6_0@bJH+GdIt~#CkhG^Q z&hM2Gx;Rb#1TLO+G|=FC7r?D_tW9?T+3-Sw_bALdx4LNgCVDdzPCmE_cb>{e!R+g6(*3p(nXb zDS(YTes5k-mx}E_pB3@pm8i7#+nYY^Q?m&|)gN-L@wBoWQ?j04la5+aA$n(yTtcllh*vhT0=mgY7;jAM_= zrIS$!^3$p-^BdbE1GDMtaiKpSF!HR+d<<62wpn}5*YUSy%ei^J!W!wJ%!8Ppa literal 2242 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 From 8af59e65c4dc19370baf01e56b9d9656aa710c6e Mon Sep 17 00:00:00 2001 From: maracle6 <45719028+maracle6@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:06:15 -0800 Subject: [PATCH 19/37] Add imagePullSecretNames value to SRS chart (#654) * ISSUE-653 Add imagePullSecretNames value to SRS chart * ISSUE-653 External image pull secrets for SRS * ISSUE-653 External image pull secrets for SRS --------- Co-authored-by: MadhuriArugula --- .../charts/srs/templates/srsservice_deployment.yaml | 7 ++++++- charts/backingservices/charts/srs/values.yaml | 3 +++ charts/backingservices/values.yaml | 4 ++++ docs/Deploying-Pega-on-AKS.md | 1 + docs/Deploying-Pega-on-EKS.md | 1 + docs/Deploying-Pega-on-GKE.md | 1 + docs/Deploying-Pega-on-PKS.md | 1 + docs/Deploying-Pega-on-openshift.md | 1 + .../src/test/backingservices/srs-deployment_test.go | 10 ++++++++++ 9 files changed, 28 insertions(+), 1 deletion(-) diff --git a/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml b/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml index feaa8bd7b..3ff3af933 100644 --- a/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml +++ b/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml @@ -17,7 +17,12 @@ spec: {{- include "srs.srs-service.match-labels" . | indent 8 }} spec: imagePullSecrets: - - name: {{ template "srsRegistrySecretName" . }} + - name: {{ template "srsRegistrySecretName" . -}} + {{ if .Values.srsRuntime.imagePullSecretNames }} + {{- range .Values.srsRuntime.imagePullSecretNames }} + - name: {{ . }} + {{- end -}} + {{ end }} containers: - name: srs-service image: {{ .Values.srsRuntime.srsImage }} diff --git a/charts/backingservices/charts/srs/values.yaml b/charts/backingservices/charts/srs/values.yaml index b662206da..60ae64954 100644 --- a/charts/backingservices/charts/srs/values.yaml +++ b/charts/backingservices/charts/srs/values.yaml @@ -10,6 +10,9 @@ srsRuntime: replicaCount: 2 # docker image of the srs-service, platform-services/search-n-reporting-service:dockerTag srsImage: "YOUR_SRS_IMAGE:TAG" + # To avoid exposing Docker credentials, optionally create a separate Docker config secret. + # Specify secret names as an array of comma-separated strings. For example: ["secret1", "secret2"] + imagePullSecretNames: [] imagePullPolicy: IfNotPresent resources: limits: diff --git a/charts/backingservices/values.yaml b/charts/backingservices/values.yaml index 0563e8bea..861c4d396 100644 --- a/charts/backingservices/values.yaml +++ b/charts/backingservices/values.yaml @@ -28,6 +28,10 @@ srs: # docker image of the srs-service, platform-services/search-n-reporting-service:dockerTag srsImage: "YOUR_SRS_IMAGE:TAG" + # To avoid exposing Docker credentials, optionally create a separate Docker config secret. + # Specify secret names as an array of comma-separated strings. For example: ["secret1", "secret2"] + imagePullSecretNames: [] + env: # AuthEnabled may be set to true when there is an authentication mechanism in place between SRS and Pega Infinity. AuthEnabled: false diff --git a/docs/Deploying-Pega-on-AKS.md b/docs/Deploying-Pega-on-AKS.md index 77357c75d..c20377d83 100644 --- a/docs/Deploying-Pega-on-AKS.md +++ b/docs/Deploying-Pega-on-AKS.md @@ -422,6 +422,7 @@ To configure the parameters in the backingservices.yaml file, download the file | global.k8sProvider: | Specify the value of your Kubernetes provider. | k8sProvider: "aks" | | srs.deploymentName: | Specify unique name for the deployment based on org app and/or srs applicable environment name. | deploymentName: "acme-demo-dev-srs" | | srs.srsRuntime.srsImage: | Specify the Pega-provided srs-service image, services/search-n-reporting-service:dockerTag that you downloaded and pushed to your Docker registry. | srs.srsRuntime.srsImage: "platform-services/search-n-reporting-service:". For `` tag (refer [compatibility matrix](../charts/backingservices/charts/srs/README.md#srs-version-compatibility-matrix)) | +| srs.srsRuntime.imagePullSecretNames: | Specify any pre-existing image pull secrets required to pull images from your organization's registry. (Optional) | imagePullSecretNames: [secret1, secret2] | | srs.srsStorage.provisionInternalESCluster: | Enabled by default to provision an Elasticsearch cluster. |

  • Set srs.srsStorage.provisionInternalESCluster:`true` and run `$ make es-prerequisite NAMESPACE=`
  • Set srs.srsStorage.provisionInternalESCluster:`false` if you want to use an existing, externally provisioned ElasticSearch cluster.
| | srs.srsStorage.domain: port: protocol: basicAuthentication: awsIAM: requireInternetAccess: | Disabled by default. Enable only when srs.srsStorage.provisionInternalESCluster is false and you want to configure SRS to use an existing, externally provisioned Elasticsearch cluster. For an Elasticsearch cluster secured with Basic Authentication, use `srs.srsStorage.basicAuthentication` section to provide access credentials. For an AWS Elasticsearch cluster secured with IAM role based authentication, use `srs.srsStorage.awsIAM` section to set the aws region where AWS Elasticsearch cluster is hosted. For unsecured managed ElasticSearch cluster do not configure these options. |
  • srs.srsStorage.domain: "\"
  • srs.srsStorage.port: "\"
  • srs.srsStorage.protocol: "\"
  • srs.srsStorage.basicAuthentication.username: "\"
  • srs.srsStorage.basicAuthentication.password: "\"
  • srs.srsStorage.awsIAM.region: "\"
  • srs.srsStorage.requireInternetAccess: "\"
| | elasticsearch: volumeClaimTemplate: resources: requests: storage: | Specify the Elasticsearch cluster disk volume size. Default is 30Gi, set this value to at least three times the size of your estimated search data size |
  • elasticsearch: volumeClaimTemplate: resources: requests: storage: "\<30Gi>”
| diff --git a/docs/Deploying-Pega-on-EKS.md b/docs/Deploying-Pega-on-EKS.md index 7a7978971..e9cb6777d 100644 --- a/docs/Deploying-Pega-on-EKS.md +++ b/docs/Deploying-Pega-on-EKS.md @@ -472,6 +472,7 @@ To configure the parameters in the backingservices.yaml file, download the file | global.k8sProvider: | Specify the value of your Kubernetes provider. | k8sProvider: "eks" | | srs.deploymentName: | Specify unique name for the deployment based on org app and/or SRS applicable environment name. | deploymentName: "acme-demo-dev-srs" | | srs.srsRuntime.srsImage: | Specify the Pega-provided SRS Docker image that you downloaded and pushed to your Docker registry. | srs.srsRuntime.srsImage: "\my-pega-srs:\". For `` tag details, see [SRS Version compatibility matrix](../charts/backingservices/charts/srs/README.md#srs-version-compatibility-matrix). | +| srs.srsRuntime.imagePullSecretNames: | Specify any pre-existing image pull secrets required to pull images from your organization's registry. (Optional) | imagePullSecretNames: [secret1, secret2] | | srs.srsStorage.provisionInternalESCluster: | Enabled by default to provision an Elasticsearch cluster. |
  • Set srs.srsStorage.provisionInternalESCluster:`true` and run `$ make es-prerequisite NAMESPACE= ELASTICSEARCH_VERSION= `
  • Set srs.srsStorage.provisionInternalESCluster:`false` if you want to use an existing, externally provisioned ElasticSearch cluster.
| | srs.srsStorage.domain: port: protocol: basicAuthentication: awsIAM: requireInternetAccess: | Disabled by default. Enable only when srs.srsStorage.provisionInternalESCluster is false and you want to configure SRS to use an existing, externally provisioned Elasticsearch cluster. For an Elasticsearch cluster secured with Basic Authentication, use `srs.srsStorage.basicAuthentication` section to provide access credentials. For an AWS Elasticsearch cluster secured with IAM role based authentication, use `srs.srsStorage.awsIAM` section to set the aws region where AWS Elasticsearch cluster is hosted. For unsecured managed ElasticSearch cluster do not configure these options. |
  • srs.srsStorage.domain: "\"
  • srs.srsStorage.port: "\"
  • srs.srsStorage.protocol: "\"
  • srs.srsStorage.basicAuthentication.username: "\"
  • srs.srsStorage.basicAuthentication.password: "\"
  • srs.srsStorage.awsIAM.region: "\"
  • srs.srsStorage.requireInternetAccess: "\"
| diff --git a/docs/Deploying-Pega-on-GKE.md b/docs/Deploying-Pega-on-GKE.md index f859da702..0e43a1438 100644 --- a/docs/Deploying-Pega-on-GKE.md +++ b/docs/Deploying-Pega-on-GKE.md @@ -235,6 +235,7 @@ To configure the parameters in the backingservices.yaml file, download the file | global.k8sProvider: | Specify the value of your Kubernetes provider. | k8sProvider: "gke" | | srs.deploymentName: | Specify unique name for the deployment based on org app and/or SRS applicable environment name. | deploymentName: "acme-demo-dev-srs" | | srs.srsRuntime.srsImage: | Specify the Pega-provided SRS Docker image that you downloaded and pushed to your Docker registry. | srs.srsRuntime.srsImage: "\my-pega-srs:\". For `` tag details, see [SRS Version compatibility matrix](../charts/backingservices/charts/srs/README.md#srs-version-compatibility-matrix). | +| srs.srsRuntime.imagePullSecretNames: | Specify any pre-existing image pull secrets required to pull images from your organization's registry. (Optional) | imagePullSecretNames: [secret1, secret2] | | srs.srsStorage.provisionInternalESCluster: | Enabled by default to provision an Elasticsearch cluster. |
  • Set srs.srsStorage.provisionInternalESCluster:`true` and run `$ make es-prerequisite NAMESPACE=`
  • Set srs.srsStorage.provisionInternalESCluster:`false` if you want to use an existing, externally provisioned ElasticSearch cluster.
| | srs.srsStorage.domain: port: protocol: basicAuthentication: awsIAM: requireInternetAccess: | Disabled by default. Enable only when srs.srsStorage.provisionInternalESCluster is false and you want to configure SRS to use an existing, externally provisioned Elasticsearch cluster. For an Elasticsearch cluster secured with Basic Authentication, use `srs.srsStorage.basicAuthentication` section to provide access credentials. For an AWS Elasticsearch cluster secured with IAM role based authentication, use `srs.srsStorage.awsIAM` section to set the aws region where AWS Elasticsearch cluster is hosted. For unsecured managed ElasticSearch cluster do not configure these options. |
  • srs.srsStorage.domain: "\"
  • srs.srsStorage.port: "\"
  • srs.srsStorage.protocol: "\"
  • srs.srsStorage.basicAuthentication.username: "\"
  • srs.srsStorage.basicAuthentication.password: "\"
  • srs.srsStorage.awsIAM.region: "\"
  • srs.srsStorage.requireInternetAccess: "\"
| | elasticsearch: volumeClaimTemplate: resources: requests: storage: | Specify the Elasticsearch cluster disk volume size. Default is 30Gi, set this value to at least three times the size of your estimated search data size |
  • elasticsearch: volumeClaimTemplate: resources: requests: storage: "\<30Gi>”
| diff --git a/docs/Deploying-Pega-on-PKS.md b/docs/Deploying-Pega-on-PKS.md index bcd4ff755..b56961d7d 100644 --- a/docs/Deploying-Pega-on-PKS.md +++ b/docs/Deploying-Pega-on-PKS.md @@ -221,6 +221,7 @@ To configure the parameters in the backingservices.yaml file, download the file |srs.enabled: | Enable the SRS to provision an internal ElasticSearch service within the SRS cluster that is defined at [ElasticSearch Helm Chart](https://github.com/elastic/helm-charts/tree/master/elasticsearch). | enabled: "true"| |srs.deploymentName: | Specify unique name for the deployment based on org app and/or SRS applicable environment name. | deploymentName: "acme-demo-dev-srs"| |srs.srsRuntime.srsImage: | Specify the Pega-provided SRS Docker image that you downloaded and pushed to your Docker registry. | srs.srsRuntime.srsImage: "\my-pega-srs:\". For `` tag details, see [SRS Version compatibility matrix](../charts/backingservices/charts/srs/README.md#srs-version-compatibility-matrix). | +| srs.srsRuntime.imagePullSecretNames: | Specify any pre-existing image pull secrets required to pull images from your organization's registry. (Optional) | imagePullSecretNames: [secret1, secret2] | | srs.srsStorage.provisionInternalESCluster: | Enabled by default to provision an Elasticsearch cluster. |
  • Set srs.srsStorage.provisionInternalESCluster:`true` and run `$ make es-prerequisite NAMESPACE=`
  • Set srs.srsStorage.provisionInternalESCluster:`false` if you want to use an existing, externally provisioned ElasticSearch cluster.
| |srs.srsStorage.domain: port: protocol: basicAuthentication: awsIAM: requireInternetAccess: | Disabled by default. Enable only when srs.srsStorage.provisionInternalESCluster is false and you want to configure SRS to use an existing, externally provisioned ElasticSearch cluster. For an ElasticSearch cluster secured with Basic Authentication, use `srs.srsStorage.basicAuthentication` section to provide access credentials. For an AWS ElasticSearch cluster secured with IAM role based authentication, use `srs.srsStorage.awsIAM` section to set the aws region where AWS ElasticSearch cluster is hosted. For unsecured managed ElasticSearch cluster do not configure these options. |
  • srs.srsStorage.domain: "\"
  • srs.srsStorage.port: "\"
  • srs.srsStorage.protocol: "\"
  • srs.srsStorage.basicAuthentication.username: "\"
  • srs.srsStorage.basicAuthentication.password: "\"
  • srs.srsStorage.awsIAM.region: "\"
  • srs.srsStorage.requireInternetAccess: "\"
| |elasticsearch:
  • esConfig: elasticsearch.yml: xpack.security.enabled: "true”
  • esConfig: elasticsearch.yml: xpack.security.transport.ssl.enabled: "true”
  • volumeClaimTemplate: resources: requests: storage: "\<30Gi>”
| To run an internal ElasticSearch service (within your deployment), specify details for both the ElasticSearch security configuration and a cluster disk volume size. While the security pack should be enabled, the transport configuration should match whether an SSL certificate is available; by default it is enabled. For the disk volume size, the default is 30Gi; set this value to at least three times the size of your estimated search data size. |
  • elasticsearch: esConfig: elasticsearch.yml:
    • xpack.security.enabled: "true”
    • xpack.security.transport.ssl.enabled: "true”
  • elasticsearch: volumeClaimTemplate: resources: requests: storage: "\<30Gi>”
| diff --git a/docs/Deploying-Pega-on-openshift.md b/docs/Deploying-Pega-on-openshift.md index 147fec677..421c25569 100644 --- a/docs/Deploying-Pega-on-openshift.md +++ b/docs/Deploying-Pega-on-openshift.md @@ -195,6 +195,7 @@ Configure the following parameters so the backingservices.yaml Helm chart matche |srs.enabled: | Enable the SRS to provision an internal ElasticSearch service within the SRS cluster that is defined at [ElasticSearch Helm Chart](https://github.com/elastic/helm-charts/tree/master/elasticsearch). | enabled: "true"| |srs.deploymentName: | Specify unique name for the deployment based on org app and/or SRS applicable environment name. | deploymentName: "acme-demo-dev-srs"| |srs.srsRuntime.srsImage: | Specify the Pega-provided SRS Docker image that you downloaded and pushed to your Docker registry. | srs.srsRuntime.srsImage: "\my-pega-srs:\". For `` tag details, see [SRS Version compatibility matrix](../charts/backingservices/charts/srs/README.md#srs-version-compatibility-matrix). | +| srs.srsRuntime.imagePullSecretNames: | Specify any pre-existing image pull secrets required to pull images from your organization's registry. (Optional) | imagePullSecretNames: [secret1, secret2] | | srs.srsStorage.provisionInternalESCluster: | Enabled by default to provision an Elasticsearch cluster. |
  • Set srs.srsStorage.provisionInternalESCluster:`true` and run `$ make es-prerequisite NAMESPACE=`
  • Set srs.srsStorage.provisionInternalESCluster:`false` if you want to use an existing, externally provisioned ElasticSearch cluster.
| |srs.srsStorage.domain: port: protocol: basicAuthentication: awsIAM: requireInternetAccess: | Disabled by default. Enable only when srs.srsStorage.provisionInternalESCluster is false and you want to configure SRS to use an existing, externally provisioned ElasticSearch cluster. For an ElasticSearch cluster secured with Basic Authentication, use `srs.srsStorage.basicAuthentication` section to provide access credentials. For an AWS ElasticSearch cluster secured with IAM role based authentication, use `srs.srsStorage.awsIAM` section to set the aws region where AWS ElasticSearch cluster is hosted. For unsecured managed ElasticSearch cluster do not configure these options. |
  • srs.srsStorage.domain: "\"
  • srs.srsStorage.port: "\"
  • srs.srsStorage.protocol: "\"
  • srs.srsStorage.basicAuthentication.username: "\"
  • srs.srsStorage.basicAuthentication.password: "\"
  • srs.srsStorage.awsIAM.region: "\"
  • srs.srsStorage.requireInternetAccess: "\"
| |elasticsearch:
  • esConfig: elasticsearch.yml: xpack.security.enabled: "true”
  • esConfig: elasticsearch.yml: xpack.security.transport.ssl.enabled: "true”
  • volumeClaimTemplate: resources: requests: storage: "\<30Gi>”
| To run an internal ElasticSearch service (within your deployment), specify details for both the ElasticSearch security configuration and a cluster disk volume size. While the security pack should be enabled, the transport configuration should match whether an SSL certificate is available; by default it is enabled. For the disk volume size, the default is 30Gi; set this value to at least three times the size of your estimated search data size. |
  • elasticsearch: esConfig: elasticsearch.yml:
    • xpack.security.enabled: "true”
    • xpack.security.transport.ssl.enabled: "true”
  • elasticsearch: volumeClaimTemplate: resources: requests: storage: "\<30Gi>”
| diff --git a/terratest/src/test/backingservices/srs-deployment_test.go b/terratest/src/test/backingservices/srs-deployment_test.go index ae7cdadf0..b7c046254 100644 --- a/terratest/src/test/backingservices/srs-deployment_test.go +++ b/terratest/src/test/backingservices/srs-deployment_test.go @@ -46,6 +46,7 @@ func TestSRSDeployment(t *testing.T){ port: "9200", protocol: "https", }, + false, }) } @@ -58,6 +59,7 @@ func TestSRSDeploymentVariables(t *testing.T){ "global.imageCredentials.registry": "docker-registry.io", "srs.srsRuntime.replicaCount": "3", "srs.srsRuntime.srsImage": "platform-services/search-n-reporting-service:1.0.0", + "srs.srsRuntime.imagePullSecretNames": "{secret1, secret2}", "srs.srsRuntime.env.AuthEnabled": "true", "srs.srsRuntime.env.OAuthPublicKeyURL": "https://acme.authenticator.com/OAuthPublicKeyURL", "srs.srsRuntime.resources.limits.cpu": "2", @@ -97,6 +99,7 @@ func TestSRSDeploymentVariables(t *testing.T){ protocol: "https", region: "us-east-1", }, + true, }) } @@ -109,6 +112,7 @@ func TestSRSDeploymentVariablesDefaultInternetEgress(t *testing.T){ "global.imageCredentials.registry": "docker-registry.io", "srs.srsRuntime.replicaCount": "3", "srs.srsRuntime.srsImage": "platform-services/search-n-reporting-service:1.0.0", + "srs.srsRuntime.imagePullSecretNames": "{secret1, secret2}", "srs.srsRuntime.env.AuthEnabled": "true", "srs.srsRuntime.env.OAuthPublicKeyURL": "https://acme.authenticator.com/OAuthPublicKeyURL", "srs.srsRuntime.resources.limits.cpu": "2", @@ -145,6 +149,7 @@ func TestSRSDeploymentVariablesDefaultInternetEgress(t *testing.T){ port: "443", protocol: "https", }, + true, }) } @@ -236,6 +241,10 @@ func VerifyDeployment(t *testing.T, pod *k8score.PodSpec, expectedSpec srsDeploy require.Equal(t, pod.Containers[0].ReadinessProbe.HTTPGet.Scheme, k8score.URIScheme("HTTP")) require.Equal(t, pod.ImagePullSecrets[0].Name, expectedSpec.name + "-reg-secret") + if expectedSpec.imagePullSecretNames { + require.Equal(t, pod.ImagePullSecrets[1].Name, "secret1") + require.Equal(t, pod.ImagePullSecrets[2].Name, "secret2") + } } type srsDeployment struct { @@ -248,6 +257,7 @@ type srsDeployment struct { internetEgress bool podLimits podResources elasticsearchEndPoint esDomain + imagePullSecretNames bool } type podResources struct { From 6414d8f16c0017eeccb3a179e660e415ab024ff6 Mon Sep 17 00:00:00 2001 From: maracle6 <45719028+maracle6@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:11:24 -0800 Subject: [PATCH 20/37] ISSUE-649 Constellation Appstatic Enhancements (#650) * ISSUE-649 Add support for ingress annotations, client created image pull secrets, and persistent storage mount for customer assets * ISSUE-649 Update README.md --------- Co-authored-by: MadhuriArugula --- .../charts/constellation/README.md | 3 +++ .../constellation/templates/clln-deployment.yaml | 16 ++++++++++++++++ .../constellation/templates/clln-ingress.yaml | 3 +++ .../charts/constellation/values.yaml | 6 ++++++ 4 files changed, 28 insertions(+) diff --git a/charts/backingservices/charts/constellation/README.md b/charts/backingservices/charts/constellation/README.md index 8b0701f3f..0d94b16cc 100644 --- a/charts/backingservices/charts/constellation/README.md +++ b/charts/backingservices/charts/constellation/README.md @@ -45,6 +45,9 @@ The values.yaml file provides configuration options to define the values for the | `cloudProvider` | Specify the cloud provider details. Accepted values are aws. | | `awsCertificateArn` | Specify the arn for the AWS ACM certificate. | | `domainName` | Specify your custom domain. | +| `ingressAnnotations` | Specify additional annotations to add to the ingress. | +| `customerAssetVolumeClaimName` | Specify the volume claim name to be used for storing customer assets. | +| `imagePullSecretNames` | Specify a list of existing ImagePullSecrets to be added to the Deployment. | | `docker`.`registry`.`url` | Specify the image registry url. | | `docker`.`registry`.`username` | Specify the username for the docker registry. | | `docker`.`registry`.`password` | Specify the password for the docker registry. | diff --git a/charts/backingservices/charts/constellation/templates/clln-deployment.yaml b/charts/backingservices/charts/constellation/templates/clln-deployment.yaml index 2e6dcf4de..da2b74117 100644 --- a/charts/backingservices/charts/constellation/templates/clln-deployment.yaml +++ b/charts/backingservices/charts/constellation/templates/clln-deployment.yaml @@ -15,11 +15,27 @@ spec: labels: app: constellation spec: + {{- if .Values.customerAssetVolumeClaimName }} + volumes: + - name: constellation-appstatic-assets + persistentVolumeClaim: + claimName: {{ .Values.customerAssetVolumeClaimName }} + {{- end }} imagePullSecrets: - name: {{ template "pegaRegistrySecret" $ }} + {{ if .Values.imagePullSecretNames }} + {{- range .Values.imagePullSecretNames }} + - name: {{ . }} + {{- end }} + {{ end }} containers: - name: constellation image: {{ .Values.docker.constellation.image }} + {{ if .Values.customerAssetVolumeClaimName }} + volumeMounts: + - name: constellation-appstatic-assets + mountPath: /usr/src/app/dist/customers + {{- end }} args: - port=3000 # constellation URL path, if you change it, you need to change ingress template files too diff --git a/charts/backingservices/charts/constellation/templates/clln-ingress.yaml b/charts/backingservices/charts/constellation/templates/clln-ingress.yaml index 46635e7f7..8a9f5ad29 100644 --- a/charts/backingservices/charts/constellation/templates/clln-ingress.yaml +++ b/charts/backingservices/charts/constellation/templates/clln-ingress.yaml @@ -14,6 +14,9 @@ metadata: alb.ingress.kubernetes.io/healthcheck-path: /c11n/buildInfo.json alb.ingress.kubernetes.io/healthcheck-port: traffic-port {{ end }} + {{- if .Values.ingressAnnotations }} + {{ toYaml .Values.ingressAnnotations | indent 4 }} + {{ end }} spec: rules: - host: {{ .Values.domainName }} diff --git a/charts/backingservices/charts/constellation/values.yaml b/charts/backingservices/charts/constellation/values.yaml index 28014d4eb..5ad744d64 100644 --- a/charts/backingservices/charts/constellation/values.yaml +++ b/charts/backingservices/charts/constellation/values.yaml @@ -7,6 +7,12 @@ cloudProvider: "aws" # For aws cloud provider enter your acm certificate ARN here. awsCertificateArn: arn:aws:acm:us-west-2:xxxxx:certificate/xxxxxxx domainName: YOUR_CUSTOM_DOMAIN_NAME_HERE +# Additional annotations for the ingress can be specified here +ingressAnnotations: +# Customer assets must be stored on a persistent storage volume. Create a volume claim and provide the name. +customerAssetVolumeClaimName: +# Provide pre-defined image pull secret names if desired +imagePullSecretNames: [] # Docker repos and tag for image docker: # If using a custom Docker registry, supply the credentials here to pull Docker images. From 7d03c0fa8e26b2b5d32f62e2e0baca16e503b236 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Tue, 9 Jan 2024 16:00:32 +0530 Subject: [PATCH 21/37] US-568873 - Changes to support cert manager (#688) * US-568873 - Changes to support cert manager. --- charts/pega/config/deploy/server.xml.tmpl | 6 +- charts/pega/templates/_helpers.tpl | 18 +- charts/pega/templates/_pega-deployment.tpl | 6 + .../pega/templates/_pega-traefik-config.tpl | 4 +- charts/pega/values.yaml | 9 +- .../data/expectedInstallDeployServer.xml.tmpl | 6 +- .../pega-tier-service-override_values.yaml | 553 ++++++++++++++++++ .../test/pega/pega-tier-deployment_test.go | 10 +- ...a_tier_deployment_with_tls_enabled_test.go | 52 ++ 9 files changed, 647 insertions(+), 17 deletions(-) create mode 100644 terratest/src/test/pega/data/pega-tier-service-override_values.yaml create mode 100644 terratest/src/test/pega/pega_tier_deployment_with_tls_enabled_test.go diff --git a/charts/pega/config/deploy/server.xml.tmpl b/charts/pega/config/deploy/server.xml.tmpl index 58833910a..66853b1a3 100644 --- a/charts/pega/config/deploy/server.xml.tmpl +++ b/charts/pega/config/deploy/server.xml.tmpl @@ -82,7 +82,7 @@ - {{ if or (exists "/opt/pega/tomcatcertsmount/TOMCAT_KEYSTORE_CONTENT") (exists "/opt/pega/tomcatcertsmount/TOMCAT_CERTIFICATE_FILE") }} + {{ if or (exists .Env.TOMCAT_KEYSTORE_CONTENT) (exists "/opt/pega/tomcatcertsmount/TOMCAT_CERTIFICATE_FILE") }} - {{ if ( and (exists "/opt/pega/tomcatcertsmount/TOMCAT_KEYSTORE_CONTENT") .Env.TOMCAT_KEYSTORE_PASSWORD ) }} + {{ if ( and (exists .Env.TOMCAT_KEYSTORE_CONTENT) .Env.TOMCAT_KEYSTORE_PASSWORD ) }} - {{ else }} diff --git a/charts/pega/templates/_helpers.tpl b/charts/pega/templates/_helpers.tpl index dfa3a714b..8a31cf448 100644 --- a/charts/pega/templates/_helpers.tpl +++ b/charts/pega/templates/_helpers.tpl @@ -58,15 +58,19 @@ {{- define "pegaVolumeTomcatKeystoreTemplate" }} - name: {{ template "pegaVolumeTomcatKeystore" }} - secret: - # This name will be referred in the volume mounts kind. - {{ if ((.node.service).tls).external_secret_name }} - secretName: {{ ((.node.service).tls).external_secret_name }} + projected: + defaultMode: 420 + sources: + {{ if (((.node.service).tls).external_secret_names) }} + {{- range (((.node.service).tls).external_secret_names) }} + - secret: + name: {{ . }} + {{- end }} {{ else }} - secretName: {{ template "pegaTomcatKeystoreSecret" $ }} + # This name will be referred in the volume mounts kind. + - secret: + name: {{ template "pegaTomcatKeystoreSecret" $ }} {{ end }} - # Used to specify permissions on files within the volume. - defaultMode: 420 {{- end}} {{- define "pegaVolumeConfig" }}pega-volume-config{{- end }} diff --git a/charts/pega/templates/_pega-deployment.tpl b/charts/pega/templates/_pega-deployment.tpl index 974b1ca61..0db586531 100644 --- a/charts/pega/templates/_pega-deployment.tpl +++ b/charts/pega/templates/_pega-deployment.tpl @@ -173,6 +173,12 @@ spec: - name: COSMOS_SETTINGS value: "Pega-UIEngine/cosmosservicesURI=/c11n" {{- end }} +{{- if ((.node.service).tls).enabled }} + - name: EXTERNAL_KEYSTORE_NAME + value: "{{ (((.node.service).tls).external_keystore_name) }}" + - name: EXTERNAL_KEYSTORE_PASSWORD + value: "{{ (((.node.service).tls).external_keystore_password) }}" +{{- end }} {{- if .custom }} {{- if .custom.env }} # Additional custom env vars diff --git a/charts/pega/templates/_pega-traefik-config.tpl b/charts/pega/templates/_pega-traefik-config.tpl index d8027d91a..9fd039266 100644 --- a/charts/pega/templates/_pega-traefik-config.tpl +++ b/charts/pega/templates/_pega-traefik-config.tpl @@ -16,8 +16,8 @@ spec: {{- end }} #For traefik, it expects the root CA certificate in a secret under the field ca.crt rootCAsSecrets: - {{- if .node.service.tls.external_secret_name }} - - {{ .node.service.tls.external_secret_name }} + {{- if .node.service.tls.external_secret_names }} + - {{ first .node.service.tls.external_secret_names }} {{- else }} - {{ .depname }}-tomcat-keystore-secret {{- end }} diff --git a/charts/pega/values.yaml b/charts/pega/values.yaml index 83c9cdf5b..8c18c13b4 100644 --- a/charts/pega/values.yaml +++ b/charts/pega/values.yaml @@ -163,7 +163,14 @@ global: # To avoid entering the certificate values in plain text, configure the keystore, keystorepassword, cacertificate parameter # values in the External Secrets Manager, and enter the external secret name below # make sure the keys in the secret should be TOMCAT_KEYSTORE_CONTENT, TOMCAT_KEYSTORE_PASSWORD and ca.crt respectively - external_secret_name: "" + # In case of providing multiple secrets, please provide them in comma separated string format. + external_secret_names: [] + # If using tools like cert-manager to generate certificates, please provide the keystore name that is autogenerated by the external tool. + # Default is TOMCAT_KEYSTORE_CONTENT + external_keystore_name: "" + # If using external secrets operator and not using standard Password Key, please provide the key for keystore password. + # Default is TOMCAT_KEYSTORE_PASSWORD + external_keystore_password: "" keystore: keystorepassword: port: 443 diff --git a/terratest/src/test/pega/data/expectedInstallDeployServer.xml.tmpl b/terratest/src/test/pega/data/expectedInstallDeployServer.xml.tmpl index 58833910a..66853b1a3 100644 --- a/terratest/src/test/pega/data/expectedInstallDeployServer.xml.tmpl +++ b/terratest/src/test/pega/data/expectedInstallDeployServer.xml.tmpl @@ -82,7 +82,7 @@ - {{ if or (exists "/opt/pega/tomcatcertsmount/TOMCAT_KEYSTORE_CONTENT") (exists "/opt/pega/tomcatcertsmount/TOMCAT_CERTIFICATE_FILE") }} + {{ if or (exists .Env.TOMCAT_KEYSTORE_CONTENT) (exists "/opt/pega/tomcatcertsmount/TOMCAT_CERTIFICATE_FILE") }} - {{ if ( and (exists "/opt/pega/tomcatcertsmount/TOMCAT_KEYSTORE_CONTENT") .Env.TOMCAT_KEYSTORE_PASSWORD ) }} + {{ if ( and (exists .Env.TOMCAT_KEYSTORE_CONTENT) .Env.TOMCAT_KEYSTORE_PASSWORD ) }} - {{ else }} diff --git a/terratest/src/test/pega/data/pega-tier-service-override_values.yaml b/terratest/src/test/pega/data/pega-tier-service-override_values.yaml new file mode 100644 index 000000000..d41756d57 --- /dev/null +++ b/terratest/src/test/pega/data/pega-tier-service-override_values.yaml @@ -0,0 +1,553 @@ +--- +global: + # This values.yaml file is an example. For more information about + # each configuration option, see the project readme. + + # Enter your Kubernetes provider. + provider: "YOUR_KUBERNETES_PROVIDER" + + deployment: + # The name specified will be used to prefix all of the Pega pods (replacing "pega" with something like "app1-dev"). + name: "pega" + + # Deploy Pega nodes + actions: + execute: "deploy" + + # Add custom certificates to be mounted to container + # to support custom certificates as plain text (less secure), pass them directly using the certificates parameter; + # to support multiple custom certificates as external secrets, specify each of your external secrets + # as an array of comma-separated strings using the certificatesSecrets parameter. + certificatesSecrets: [] + certificates: + + # Add krb5.conf file content here. + # Feature is used for Decisioning data flows to fetch data from Kafka or HBase streams + kerberos: + + # If a storage class to be passed to the VolumeClaimTemplates in search and stream pods, it can be specified here: + storageClassName: "" + # Provide JDBC connection information to the Pega relational database + # If you are installing or upgrading on IBM DB2, update the udb.conf file in the /charts/pega/charts/installer/config/udb directory with any additional connection properties. + jdbc: + # url Valid values are: + # + # Oracle jdbc:oracle:thin:@//localhost:1521/dbName + # IBM DB/2 z / OS jdbc:db2://localhost:50000/dbName + # IBM DB/2 jdbc:db2://localhost:50000/dbName:fullyMaterializeLobData=true;fullyMaterializeInputStreams=true; + # progressiveStreaming=2;useJDBC4ColumnNameAndLabelSemantics=2; + # SQL Server jdbc:sqlserver://localhost:1433;databaseName=dbName;selectMethod=cursor;sendStringParametersAsUnicode=false + # PostgreSQL jdbc:postgresql://localhost:5432/dbName + url: "YOUR_JDBC_URL" + # driverClass -- jdbc class. Valid values are: + # + # Oracle oracle.jdbc.OracleDriver + # IBM DB/2 com.ibm.db2.jcc.DB2Driver + # SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver + # PostgreSQL org.postgresql.Driver + driverClass: "YOUR_JDBC_DRIVER_CLASS" + # pega.database.type Valid values are: mssql, oracledate, udb, db2zos, postgres + dbType: "YOUR_DATABASE_TYPE" + # For databases that use multiple JDBC driver files (such as DB2), specify comma separated values for 'driverUri' + driverUri: "YOUR_JDBC_DRIVER_URI" + username: "YOUR_JDBC_USERNAME" + password: "YOUR_JDBC_PASSWORD" + # To avoid exposing username & password, leave the jdbc.password & jdbc.username parameters empty (no quotes), + # configure JDBC username & password parameters in the External Secrets Manager, and enter the external secret for the credentials + # make sure the keys in the secret should be DB_USERNAME and DB_PASSWORD respectively + external_secret_name: "" + # CUSTOM CONNECTION PROPERTIES + # Use the connectionProperties parameter to pass connection settings to your deployment + # by adding a list of semi-colon-delimited required connection setting. The list string must end with ";". + # For example, you can set a custom authentication using Azure Managed Identity and avoid using a password. + # To pass an Authentication method and a managed identity, MSI Client ID, + # set: connectionProperties: "Authentication=ActiveDirectoryMSI;msiClientId=;" + connectionProperties: "" + rulesSchema: "YOUR_RULES_SCHEMA" + dataSchema: "YOUR_DATA_SCHEMA" + customerDataSchema: "" + + customArtifactory: + # If you use a secured custom artifactory to manager your JDBC driver, + # provide the authentication details below by filling in the appropriate authentication section, + # either basic or apiKey. + authentication: + # Provide the basic authentication credentials or the API key authentication details to satisfy your custom artifactory authentication mechanism. + basic: + username: "" + password: "" + apiKey: + headerName: "" + value: "" + # To avoid exposing basic.username,basic.password,apiKey.headerName,apiKey.value parameters, configure the + # basic.username,basic.password,apiKey.headerName,apiKey.value parameters in External Secrets Manager, and enter the external secret for the credentials + # make sure the keys in the secret should be CUSTOM_ARTIFACTORY_USERNAME , CUSTOM_ARTIFACTORY_PASSWORD , CUSTOM_ARTIFACTORY_APIKEY_HEADER , CUSTOM_ARTIFACTORY_APIKEY + external_secret_name: "" + # Leave customArtifactory.enableSSLVerification enabled to ensure secure access to your custom artifactory; + # when customArtifactory.enableSSLVerification is false, SSL verification is skipped and establishes an insecure connection. + enableSSLVerification: true + # Provide a required domain certificate for your custom artifactory; if none is required, leave this field blank. + certificate: + + docker: + # If using a custom Docker registry, supply the credentials here to pull Docker images. + registry: + url: "YOUR_DOCKER_REGISTRY" + username: "YOUR_DOCKER_REGISTRY_USERNAME" + password: "YOUR_DOCKER_REGISTRY_PASSWORD" + # To avoid exposing Docker registry details, create secrets to manage your Docker registry credentials. + # Specify secret names as an array of comma-separated strings in double quotation marks using the imagePullSecretNames parameter. For example: ["secret1", "secret2"] + imagePullSecretNames: [] + # Docker image information for the Pega docker image, containing the application server. + pega: + image: "pegasystems/pega" + + utilityImages: + busybox: + image: busybox:1.31.0 + imagePullPolicy: IfNotPresent + k8s_wait_for: + image: pegasystems/k8s-wait-for + imagePullPolicy: "IfNotPresent" + # waitTimeSeconds: 2 + # maxRetries: 1 + + # Upgrade specific properties + upgrade: + # Configure only for aks/pks + # Run "kubectl cluster-info" command to get the service host and https service port of kubernetes api server. + # Example - Kubernetes master is running at https://: + kube-apiserver: + serviceHost: "API_SERVICE_ADDRESS" + httpsServicePort: "SERVICE_PORT_HTTPS" + + # Set the `compressedConfigurations` parameter to `true` when the configuration files under charts/pega/config/deploy are in compressed format. + # For more information, see the “Pega compressed configuration files” section in the Pega Helm chart documentation. + compressedConfigurations: false + + # Specify the Pega tiers to deploy + tier: + - name: "web" + # Create a an interactive tier for web users. This tier uses + # the WebUser node type and will be exposed via a service to + # the load balancer. + nodeType: "WebUser" + + # Pega requestor specific properties + requestor: + # Inactivity time after which requestor is passivated + passivationTimeSec: 900 + + + service: + # For help configuring the service block, see the Helm chart documentation + # https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#service + httpEnabled: true + port: 80 + targetPort: 8080 + # Use this parameter to deploy a specific type of service using the serviceType parameter and specify the type of service in double quotes. + # This is an optional value and should be used based on the use case. + # This should be set only in case of eks, gke and other cloud providers. This option should not be used for k8s and minikube. + # For example if you want to deploy a service of type LoadBalancer, uncomment the following line and specify serviceType: "LoadBalancer" + # serviceType: "" + # Specify the CIDR ranges to restrict the service access to the given CIDR range. + # Each new CIDR block should be added in a separate line. + # Should be used only when serviceType is set to LoadBalancer. + # Uncomment the following lines and replace the CIDR blocks with your configuration requirements. + # loadBalancerSourceRanges: + # - "123.123.123.0/24" + # - "128.128.128.64/32" + # To configure TLS between the ingress/load balancer and the backend, set the following: + tls: + enabled: true + # To avoid entering the certificate values in plain text, configure the keystore, keystorepassword, cacertificate parameter + # values in the External Secrets Manager, and enter the external secret name below + # make sure the keys in the secret should be TOMCAT_KEYSTORE_CONTENT, TOMCAT_KEYSTORE_PASSWORD and ca.crt respectively + external_secret_names: [] + # If using tools like cert-manager to generate certificates, please provide the keystore name that is autogenerated by the external tool. + external_keystore_name: "EXTERNAL_KEYSTORE_NAME" + # If using external secrets operator and not using standard Password Key, please provide the key for keystore password. + # Default is TOMCAT_KEYSTORE_PASSWORD + external_keystore_password: "EXTERNAL_KEYSTORE_PASSWORD" + keystore: + keystorepassword: + port: 443 + targetPort: 8443 + # set the value of CA certificate here in case of baremetal/openshift deployments - CA certificate should be in base64 format + # pass the certificateChainFile file if you are using certificateFile and certificateKeyFile + cacertificate: + # provide the SSL certificate and private key as a PEM format + certificateFile: + certificateKeyFile: + # if you will deploy traefik addon chart and enable traefik, set enabled=true; otherwise leave the default setting. + traefik: + enabled: false + # the SAN of the certificate present inside the container + serverName: "" + # set insecureSkipVerify=true, if the certificate verification has to be skipped + insecureSkipVerify: false + + ingress: + # For help configuring the ingress block including TLS, see the Helm chart documentation + # https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#ingress + + # Enter the domain name to access web nodes via a load balancer. + # e.g. web.mypega.example.com + domain: "YOUR_WEB_NODE_DOMAIN" + # Configure custom path for given host along with pathType. Default pathType is ImplementationSpecific. + # path: + # pathType: + tls: + # Enable TLS encryption + enabled: true + # secretName: + # useManagedCertificate: false + # ssl_annotation: + # For Openshift, Pega deployments enable TLS to secure the connection + # from the browser to the router by creating the route using reencrypt termination policy. + # Add your certificate, the corresponding key using the appropriate .pem or .crt format and + # specify a CA certificate to validate the endpoint certificate. + certificate: + key: + cacertificate: + + replicas: 1 + javaOpts: "" + pegaDiagnosticUser: "" + pegaDiagnosticPassword: "" + + deploymentStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + + livenessProbe: + port: 8081 + + # Optionally overridde default resource specifications + # cpuRequest: 2 + # memRequest: "12Gi" + # cpuLimit: 4 + # memLimit: "12Gi" + # initialHeap: "4096m" + # maxHeap: "8192m" + + # To configure an alternative user for custom image, set value for runAsUser. + # To configure an alternative group for volume mounts, set value for fsGroup + # See, https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#security-context + # securityContext: + # runAsUser: 9001 + # fsGroup: 0 + + hpa: + enabled: true + + # Set enabled to true to include a Pod Disruption Budget for this tier. + # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable + # value and comment out the other parameter. + pdb: + enabled: false + minAvailable: 1 + # maxUnavailable: "50%" + + - name: "batch" + # Create a background tier for batch processing. This tier uses + # a collection of background node types and will not be exposed to + # the load balancer. + nodeType: "BackgroundProcessing,Search,Batch,RealTime,Custom1,Custom2,Custom3,Custom4,Custom5,BIX" + + replicas: 1 + javaOpts: "" + + pegaDiagnosticUser: "" + pegaDiagnosticPassword: "" + + deploymentStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + + livenessProbe: + port: 8081 + + # To configure an alternative user for your custom image, set value for runAsUser + # To configure an alternative group for volume mounts, set value for fsGroup + # See, https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#security-context + # securityContext: + # runAsUser: 9001 + # fsGroup: 0 + + hpa: + enabled: true + + # Set enabled to true to include a Pod Disruption Budget for this tier. + # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable + # value and comment out the other parameter. + pdb: + enabled: false + minAvailable: 1 + # maxUnavailable: "50%" + + - name: "stream" + # Create a stream tier for queue processing. This tier deploys + # as a stateful set to ensure durability of queued data. It may + # be optionally exposed to the load balancer. + # Note: Stream tier is deprecated, please enable externalized Kafka service configuration under External Services. + # When externalized Kafka service is enabled, we should remove the entire stream tier. + nodeType: "Stream" + + # Pega requestor specific properties + requestor: + # Inactivity time after which requestor is passivated + passivationTimeSec: 900 + + service: + port: 7003 + targetPort: 7003 + + # If a nodeSelector is required for this or any tier, it may be specified here: + # nodeSelector: + # disktype: ssd + + ingress: + # Enter the domain name to access web nodes via a load balancer. + # e.g. web.mypega.example.com + domain: "YOUR_STREAM_NODE_DOMAIN" + tls: + # Enable TLS encryption + enabled: true + # secretName: + # useManagedCertificate: false + # ssl_annotation: + + livenessProbe: + port: 8081 + + # To configure an alternative user for your custom image, set value for runAsUser + # To configure an alternative group for volume mounts, set value for fsGroup + # See, https://github.com/pegasystems/pega-helm-charts/blob/master/charts/pega/README.md#security-context + # securityContext: + # runAsUser: 9001 + # fsGroup: 0 + + replicas: 2 + + volumeClaimTemplate: + resources: + requests: + storage: 5Gi + + # Set enabled to true to include a Pod Disruption Budget for this tier. + # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable + # value and comment out the other parameter. + pdb: + enabled: false + minAvailable: 1 + # maxUnavailable: "50%" + +# External services + +# Cassandra automatic deployment settings. +cassandra: + enabled: true + persistence: + enabled: true + resources: + requests: + memory: "4Gi" + cpu: 2 + limits: + memory: "8Gi" + cpu: 4 + +# DDS (external Cassandra) connection settings. +# These settings should only be modified if you are using a custom Cassandra deployment. +# To deploy Pega without Cassandra, comment out or delete the following dds section and set +# the cassandra.enabled property above to false. +dds: + # A comma separated list of hosts in the Cassandra cluster. + externalNodes: "" + # TCP Port to connect to cassandra. + port: "9042" + # The username for authentication with the Cassandra cluster. + username: "dnode_ext" + # The password for authentication with the Cassandra cluster. + password: "dnode_ext" + # Whether to enable client encryption on the Cassandra connection. + clientEncryption: false + # If required, provide the trustStore certificate file name. + # When using a trustStore certificate, you must also include a Kubernetes secret name that contains the trustStore certificate in the global.certificatesSecrets parameter. + # Pega deployments only support trustStores using the Java Key Store (.jks) format. + trustStore: "" + # If required provide trustStorePassword value in plain text. + trustStorePassword: "" + # If required, provide the keystore certificate file name. + # When using a keystore certificate, you must also include a Kubernetes secret name that contains the keystore certificate in the global.certificatesSecrets parameter. + # Pega deployments only support keystore using the Java Key Store (.jks) format. + keyStore: "" + # If required provide keyStorePassword value in plain text. + keyStorePassword: "" + # To avoid exposing username,password,trustStorePassword,keyStorePassword parameters, configure the + # username,password,trustStorePassword,keyStorePassword parameters in External Secrets Manager, and enter the external secret for the credentials + # make sure the keys in the secret should be CASSANDRA_USERNAME, CASSANDRA_PASSWORD , CASSANDRA_TRUSTSTORE_PASSWORD , CASSANDRA_KEYSTORE_PASSWORD + external_secret_name: "" + # Enable asynchronous processing of records in DDS Dataset save operation. Failures to store individual records will + # not interrupt Dataset save operations. + asyncProcessingEnabled: false + # Specify a prefix to use when creating Pega-managed keyspaces in Cassandra. + keyspacesPrefix: "" + # Enable an extended token aware policy for use when a Cassandra range query runs. When enabled this policy selects a + # token from the token range to determine which Cassandra node to send the request. Before you can enable this policy, + # you must configure the token range partitioner. + extendedTokenAwarePolicy: false + # Enable a latency awareness policy, which collects the latencies of the queries for each Cassandra node and maintains + # a per-node latency score (an average). + latencyAwarePolicy: false + # Enable the use of a customized retry policy for your Pega Platform deployment. After enabling this policy in your + # deployment configuration, Cassandra queries that timeout will be retried. The number of retries may be configured + # using the dynamic system setting (DSS): dnode/cassandra_custom_retry_policy/retryCount. If not configured, queries + # will be retried once. + customRetryPolicy: false + # Enable the use of a customized retry policy for your Pega Platform deployment for Pega Platform ’23 and earlier + # releases. After you enable this policy in your deployment configuration, the deployment retries Cassandra queries + # that time out. Configure the number of retries using the dynamic system setting (DSS): + # dnode/cassandra_custom_retry_policy/retryCount. The default is 1, so if you do not specify a retry count, timed out + # queries are retried once. + customRetryPolicyEnabled: false + # Use this parameter in Pega Platform '24 and later instead of `customRetryPolicy`. Configure the number of retries + # using the `customRetryPolicyCount` property. + customRetryPolicyCount: 1 + # Specify the number of retry attempts when `customRetryPolicyEnabled` is true. For Pega Platform '23 and earlier + # releases use the dynamic system setting (DSS): dnode/cassandra_custom_retry_policy/retryCount. + speculativeExecutionPolicy: false + # Enable the speculative execution policy for retrieving data from your Cassandra service for Pega Platform '23 and + # earlier releases. When enabled, Pega Platform sends a query to multiple nodes in your Cassandra service and + # processes the first response. This provides lower perceived latencies for your deployment, but puts greater load + # on your Cassandra service. Configure the speculative execution delay and max executions using the following dynamic + # system settings (DSS): dnode/cassandra_speculative_execution_policy/delay and + # dnode/cassandra_speculative_execution_policy/max_executions. + speculativeExecutionPolicyEnabled: false + # Use this parameter in Pega Platform '24 and later instead of `speculativeExecutionPolicy`. Configure the + # speculative execution delay and max executions using the `speculativeExecutionPolicyDelay` and + # `speculativeExecutionPolicyMaxExecutions` properties. + speculativeExecutionPolicyDelay: 100 + # Specify the delay in milliseconds before speculative executions are made when `speculativeExecutionPolicyEnabled` is + # true. For Pega Platform '23 and earlier releases use the dynamic system setting (DSS): + # dnode/cassandra_speculative_execution_policy/delay. + speculativeExecutionPolicyMaxExecutions: 2 + # Specify the maximum number of speculative execution attempts when `speculativeExecutionPolicyEnabled` is true. For + # Pega Platform '23 and earlier releases use the dynamic system setting (DSS): + # dnode/cassandra_speculative_execution_policy/max_executions. + jmxMetricsEnabled: true + # Enable reporting of DDS SDK metrics to a Comma Separated Value (CSV) format for use by your organization to monitor + # your Cassandra service. If you enable this property, use the Pega Platform DSS: + # dnode/ddsclient/metrics/csv_directory to customize the filepath to which the deployment writes CSV files. By + # default, after you enable this property, CSV files will be written to the Pega Platform work directory. + csvMetricsEnabled: false + # Enable reporting of DDS SDK metrics to your Pega Platform logs. + logMetricsEnabled: false + +# Elasticsearch deployment settings. +# Note: This Elasticsearch deployment is used for Pega search, and is not the same Elasticsearch deployment used by the EFK stack. +# These search nodes will be deployed regardless of the Elasticsearch configuration above. +# Refer to README document to configure `Search and Reporting Service` as a search functionality provider under this section. +pegasearch: + image: "pegasystems/search" + memLimit: "3Gi" + replicas: 1 + +# Pega Installer settings. +installer: + image: "YOUR_INSTALLER_IMAGE:TAG" + # Set the initial administrator@pega.com password for your installation. This will need to be changed at first login. + # The adminPassword value cannot start with "@". + adminPassword: "ADMIN_PASSWORD" + # Upgrade specific properties + upgrade: + # Type of upgrade + # Valid upgradeType values are 'in-place' , 'zero-downtime' , 'custom' , 'out-of-place-rules' , 'out-of-place-data' . + upgradeType: "in-place" + # Specify a name for a target rules schema that the upgrade process creates for patches and upgrades. + targetRulesSchema: "" + # Specify a name for a target data schema that the upgrade process creates for patches and upgrades. + # For postgres databases that you are upgrading from Pega Infinity version 8.4.0 and later + # And for Oracle databases that you are upgrading from Pega Infinity version 8.4.3 and later. + targetDataSchema: "" + # Specify the username and password to access the pre-upgrade Pega Platform to perform pre- and post- actions during zero-downtime upgrades. + pegaRESTUsername: "" + pegaRESTPassword: "" + +# Hazelcast settings (applicable from Pega 8.6) +hazelcast: + # Hazelcast docker image for platform version 8.6 through 8.7.x + image: "YOUR_HAZELCAST_IMAGE:TAG" + # Hazelcast docker image for platform version 8.8 and later + clusteringServiceImage: "YOUR_CLUSTERING_SERVICE_IMAGE:TAG" + + # Setting below to true will deploy Pega Platform using a client-server Hazelcast model for version 8.6 through 8.7.x. + # Note: Make sure to set this value as "false" in case of Pega Platform version before "8.6". If not set this will fail the installation. + enabled: true + + # Setting below to true will deploy Pega Platform using a client-server Hazelcast model for version 8.8 and later. + clusteringServiceEnabled: false + + # Setting related to Hazelcast migration. + migration: + # Set to `true` to initiate the migration job. + initiateMigration: false + # Reference the `platform/clustering-service-kubectl` Docker image to create the migration job. + migrationJobImage: "YOUR_MIGRATION_JOB_IMAGE:TAG" + # Set to `true` when migrating from embedded Hazelcast. + embeddedToCSMigration: false + + # No. of initial members to join + replicas: 3 + # UserName in the client-server Hazelcast model authentication. This setting is exposed and not secure. + username: "" + # Password in the client-server Hazelcast model authentication. This setting is exposed and not secure. + password: "" + # To avoid exposing username and password parameters, leave these parameters empty and configure + # these cluster settings using an External Secrets Manager. Use the following keys in the secret: + # HZ_CS_AUTH_USERNAME for username and HZ_CS_AUTH_PASSWORD for password. + # Enter the external secret for these credentials below. + external_secret_name: "" + +# Stream (externalized Kafka service) settings. +stream: + # Beginning with Pega Platform '23, enabled by default; when disabled, your deployment does not use a"Kafka stream service" configuration. + enabled: true + # Provide externalized Kafka service broker urls. + bootstrapServer: "" + # Provide Security Protocol used to communicate with kafka brokers. Supported values are: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL. + securityProtocol: PLAINTEXT + # If required, provide trustStore certificate file name + # When using a trustStore certificate, you must also include a Kubernetes secret name, that contains the trustStore certificate, + # in the global.certificatesSecrets parameter. + # Pega deployments only support trustStores using the Java Key Store (.jks) format. + trustStore: "" + # If required provide trustStorePassword value in plain text. + trustStorePassword: "" + # If required, provide keyStore certificate file name + # When using a keyStore certificate, you must also include a Kubernetes secret name, that contains the keyStore certificate, + # in the global.certificatesSecrets parameter. + # Pega deployments only support keyStores using the Java Key Store (.jks) format. + keyStore: "" + # If required, provide keyStore value in plain text. + keyStorePassword: "" + # If required, provide jaasConfig value in plain text. + jaasConfig: "" + # If required, provide a SASL mechanism**. Supported values are: PLAIN, SCRAM-SHA-256, SCRAM-SHA-512. + saslMechanism: PLAIN + # By default, topics originating from Pega Platform have the pega- prefix, + # so that it is easy to distinguish them from topics created by other applications. + # Pega supports customizing the name pattern for your Externalized Kafka configuration for each deployment. + streamNamePattern: "pega-{stream.name}" + # Your replicationFactor value cannot be more than the number of Kafka brokers and 3. + replicationFactor: "1" + # To avoid exposing trustStorePassword, keyStorePassword, and jaasConfig parameters, leave the values empty and + # configure them using an External Secrets Manager, making sure you configure the keys in the secret in the order: + # STREAM_TRUSTSTORE_PASSWORD, STREAM_KEYSTORE_PASSWORD and STREAM_JAAS_CONFIG. + # Enter the external secret name below. + external_secret_name: "" diff --git a/terratest/src/test/pega/pega-tier-deployment_test.go b/terratest/src/test/pega/pega-tier-deployment_test.go index 39ed19f46..38b5eebc4 100644 --- a/terratest/src/test/pega/pega-tier-deployment_test.go +++ b/terratest/src/test/pega/pega-tier-deployment_test.go @@ -90,6 +90,7 @@ func TestPegaTierDeploymentWithFSGroup(t *testing.T) { "global.tier[2].securityContext.fsGroup": key, // stream tier }, } + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) yamlSplit := strings.Split(yamlContent, "---") @@ -165,7 +166,6 @@ func VerifyDeployment(t *testing.T, pod *k8score.PodSpec, expectedSpec pegaDeplo for i := 0; i < count; i++ { actualInitContainerNames[i] = actualInitContainers[i].Name } - //require.Equal(t, expectedSpec.initContainers, actualInitContainerNames) NEED TO CHANGE FOR "install-deploy" VerifyInitContainerData(t, actualInitContainers, options) require.Equal(t, "pega-web-tomcat", pod.Containers[0].Name) @@ -190,6 +190,14 @@ func VerifyDeployment(t *testing.T, pod *k8score.PodSpec, expectedSpec pegaDeplo require.Equal(t, "COSMOS_SETTINGS", pod.Containers[0].Env[envIndex].Name) require.Equal(t, "Pega-UIEngine/cosmosservicesURI=/c11n", pod.Containers[0].Env[envIndex].Value) } + if options.ValuesFiles != nil && expectedSpec.name == getObjName(options, "-web") && options.SetStrValues["service.tls.enabled"] == "true" { + envIndex++ + require.Equal(t, "EXTERNAL_KEYSTORE_NAME", pod.Containers[0].Env[envIndex].Name) + require.Equal(t, "EXTERNAL_KEYSTORE_NAME", pod.Containers[0].Env[envIndex].Value) + envIndex++ + require.Equal(t, "EXTERNAL_KEYSTORE_PASSWORD", pod.Containers[0].Env[envIndex].Name) + require.Equal(t, "EXTERNAL_KEYSTORE_PASSWORD", pod.Containers[0].Env[envIndex].Value) + } envIndex++ require.Equal(t, "JAVA_OPTS", pod.Containers[0].Env[envIndex].Name) require.Equal(t, "", pod.Containers[0].Env[envIndex].Value) diff --git a/terratest/src/test/pega/pega_tier_deployment_with_tls_enabled_test.go b/terratest/src/test/pega/pega_tier_deployment_with_tls_enabled_test.go new file mode 100644 index 000000000..5d3be6121 --- /dev/null +++ b/terratest/src/test/pega/pega_tier_deployment_with_tls_enabled_test.go @@ -0,0 +1,52 @@ +package pega + +import ( + "fmt" + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/stretchr/testify/require" + "path/filepath" + "strings" + "testing" +) + +func TestPegaTierDeploymentWithTlsEnabled(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + + for _, vendor := range supportedVendors { + + for _, operation := range supportedOperations { + + for _, depName := range deploymentNames { + + fmt.Println(vendor + "-" + operation) + + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "global.deployment.name": depName, + "installer.upgrade.upgradeType": "zero-downtime", + "global.storageClassName": "storage-class", + }, + ValuesFiles: []string{"data/pega-tier-service-override_values.yaml"}, + SetStrValues: map[string]string{ + "service.tls.enabled": "true", + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) + yamlSplit := strings.Split(yamlContent, "---") + assertWeb(t, yamlSplit[1], options) + assertBatch(t, yamlSplit[2], options) + assertStream(t, yamlSplit[3], options) + assertStreamWithSorageClass(t, yamlSplit[3], options) + + } + } + } +} From 132cedd0888ddb0cfb66557e874aa07d7599f035 Mon Sep 17 00:00:00 2001 From: khick77 Date: Fri, 19 Jan 2024 13:23:47 -0500 Subject: [PATCH 22/37] BUG-841263 (#692) Removed references to Pega Platform 8.2, as we only support 8.3+ --- README.md | 2 +- charts/pega/README.md | 2 +- docs/patching-pega-deployment.md | 21 ++++++--------------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 7033631d5..c92b25ac0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Pega deployment on Kubernetes -This project provides Helm charts and basic examples for deploying Pega on Kubernetes. You will also need to download the required [installation kit](https://community.pega.com/knowledgebase/products/platform/deploy) from the Pega Community which includes rules and data to preload into your relational database. Deploying Pega on Kubernetes requires Pega Infinity 8.2 or later. +This project provides Helm charts and basic examples for deploying Pega on Kubernetes. You will also need to download the required [installation kit](https://community.pega.com/knowledgebase/products/platform/deploy) from the Pega Community which includes rules and data to preload into your relational database. Deploying Pega on Kubernetes requires Pega Infinity 8.3 or later. [![Build Status](https://github.com/pegasystems/pega-helm-charts/actions/workflows/github-actions-build.yml/badge.svg)](https://github.com/pegasystems/pega-helm-charts/actions/workflows/github-actions-build.yml) [![GitHub release](https://img.shields.io/github/release/pegasystems/pega-helm-charts.svg)](https://github.com/pegasystems/pega-helm-charts/releases) diff --git a/charts/pega/README.md b/charts/pega/README.md index 3ac46d82a..97e6762a5 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -971,7 +971,7 @@ Parameter | Description | Default value `upgrade.upgradeType:` |Specify the type of process, applying a patch or upgrading. | See the next table for details. `upgrade.upgradeSteps:` |Specify the steps of a `custom` upgrade process that you want to complete. For `zero-downtime`, `out-of-place-rules`, `out-of-place-data`, or `in-place` upgrades, leave this parameter empty. |
    `enable_cluster_upgrade` `rules_migration` `rules_upgrade` `data_upgrade` `disable_cluster_upgrade`
`upgrade.targetRulesSchema:` |Specify the name of the schema you created the process creates for the new rules schema. | `""` -`upgrade.targetDataSchema:` | For patches to 8.4 and later or upgrades from 8.4.2 and later, specify the name of the schema the process creates for the temporary data schema. After the patch or upgrade, you must delete this temporary data schema from your database. For 8.2 or 8.3 Pega software patches, you can leave this value empty, as is (do not add blank text). | `""` +`upgrade.targetDataSchema:` | For patches to 8.4 and later or upgrades from 8.4.2 and later, specify the name of the schema the process creates for the temporary data schema. After the patch or upgrade, you must delete this temporary data schema from your database. For 8.3 Pega software patches, you can leave this value empty, as is (do not add blank text). | `""` Upgrade type | Description --- | --- diff --git a/docs/patching-pega-deployment.md b/docs/patching-pega-deployment.md index 3d86af109..ce0fc6244 100644 --- a/docs/patching-pega-deployment.md +++ b/docs/patching-pega-deployment.md @@ -21,24 +21,15 @@ Client-managed cloud clients use the same Pega Kubernetes tools and Helm charts 2. Edit the pega Helm chart by editing parameters to specify "upgrade-deploy" your software with the software contained in your provided patch image. - [Applying a zero-downtime Pega Platform patch using Helm charts - 120-minutes](#applying-a-zero-downtime-pega-platform-patch-using-helm-charts--120-minutes). -3. **For deployments running Pega Infinity 8.2.1 through 8.2.7 only:** Create a new blank rules schema in your existing database. Leave this new schema empty. If you are running Pega Infinity 8.3 or higher, you can skip this step, since the patch scripts in your deployment automate the creation of these blank schemas. - - If you create a new schema, create each schema name in accordance with the requirements of your deployment database type: - - Oracle/DB2 databases force unquoted identifiers to uppercase. - - PostgreSQL databases force unquoted identifiers to lowercase. - - MSSQL uses case sensitive identifiers; therefore you must use a consistent naming convention in order to avoid issues with your deployment. - - Pega does not support quoted identifiers in database schema names, so do not wrap your schema name with single quotes. - -4. Apply the patch by using the `helm upgrade release --namespace mypega` command as directed in the deployment section - [Patching your Pega Platform deployment using the command line](#patching-your-pega-platform-deployment-using-the-command-line). +3. Apply the patch by using the `helm upgrade release --namespace mypega` command as directed in the deployment section - [Patching your Pega Platform deployment using the command line](#patching-your-pega-platform-deployment-using-the-command-line). ## Assumptions and prerequisites The process to patch your deployment assumes: -- Your Kubernetes environment has not changed and you are using the same Pega charts with which you originally deployed. +- Your Kubernetes environment has not changed, and you are using the same Pega charts with which you originally deployed. -- Your original deployment used Pega Platform 8.2.1 or later. +- Your original deployment used Pega Platform 8.3.0 or later. ## Applying a zero-downtime Pega Platform patch using Helm charts – 120 minutes @@ -51,7 +42,7 @@ To complete a zero downtime patch, you must configure the following settings in - Specify action.execute: upgrade-deploy to invoke the zero-downtime patch process. - Specify the schema name or names that will be upgraded: - **For 8.4 and later**: specify both schema names, since the process involves migrating rules to and from each schema (jdbc.rulesSchema: "YOUR_RULES_SCHEMA" and jdbc.dataSchema: "YOUR_DATA_SCHEMA"). - - **For 8.2 and 8.3**: specify the rules schema since the process only involves migrating rules to and from the existing rule schema (jdbc.rulesSchema: "YOUR_RULES_SCHEMA"); leave the existing "YOUR_RULES_SCHEMA" value (do not leave blank text). + - **For 8.3**: specify the rules schema since the process only involves migrating rules to and from the existing rule schema (jdbc.rulesSchema: "YOUR_RULES_SCHEMA"); leave the existing "YOUR_RULES_SCHEMA" value (do not leave blank text). - Ensure one of the following: - You pushed the images for your patch to the same repository that you used for your installation repository and the credentials for your repository account are the same as those in your `pega` Helm chart. - You pushed the images for your patch to a new repository and you update the parameters with your credentials for this new repository account in your `pega` Helm chart. @@ -65,7 +56,7 @@ To complete a zero downtime patch, you must configure the following settings in - In the installer section of the Helm chart, update the following: - Update the tagging details, including the version and date of your Pega-provided `platform/installer` Docker image, that you downloaded to support your patch. - Specify an `zero-downtime` upgrade to apply a patch using the zero-downtime patch process. - - **For patches to 8.4 and later**, specify the new target new rules and temporary data schema names that the process creates in your existing database to support the patch process within the quotes. **For 8.2 or 8.3 Pega software patches**, you can leave this value empty, as is (do not leave blank text). + - **For patches to 8.4 and later**, specify the new target new rules and temporary data schema names that the process creates in your existing database to support the patch process within the quotes. **For 8.3 Pega software patches**, you can leave this value empty, as is (do not leave blank text). You can leave the existing customized parameters as is; the patch process will use the remaining existing settings in your deployment. @@ -88,7 +79,7 @@ Complete the following steps. | installer.adminPassword: | Specify an initial administrator@pega.com password for your installation. This will need to be changed at first login. The adminPassword value cannot start with "@".| adminPassword: "\" | | installer.upgrade.upgradeType | Specify an zero-downtime upgrade to apply a patch using the zero-downtime patch process. | upgradeType: "zero-downtime" | | installer.upgrade.targetRulesSchema | Specify a new rules schema name that the process creates in your existing database to support the patch process within the quotes. | targetRulesSchema: "" | - | installer.upgrade.targetDataSchema | For patches to 8.4 and later, specify a new target data schema name that the process creates in your existing database to support the patch process within the quotes. For 8.2 or 8.3 Pega software patches, you can leave this value empty, as is (do not leave blank text). | targetDataSchema: "" | + | installer.upgrade.targetDataSchema | For patches to 8.4 and later, specify a new target data schema name that the process creates in your existing database to support the patch process within the quotes. For 8.3 Pega software patches, you can leave this value empty, as is (do not leave blank text). | targetDataSchema: "" | 2. Save the file. ### Patching your Pega Platform deployment using the command line From d45122870a6ea26004333fb46c5ba25ef759342a Mon Sep 17 00:00:00 2001 From: hsomu <69858281+hsomu@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:05:20 +0530 Subject: [PATCH 23/37] US-530858: Helm chart and documentation updates for updating to elasticsearch 8.x version (#674) * US-530858: Helm chart and documentation updates for updating to elasticsearch 8.x version * US-530858: Helm chart and documentation updates for updating to elasticsearch 8.x version * US-530858: Helm chart and documentation updates for updating to elasticsearch 8.x version --------- Co-authored-by: somuh --- charts/backingservices/charts/srs/README.md | 87 +++++++++++++++---- .../charts/srs/templates/_helpers.tpl | 9 +- charts/backingservices/values.yaml | 25 ++++-- 3 files changed, 94 insertions(+), 27 deletions(-) diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index c8602b67a..286660c01 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -15,23 +15,76 @@ The service deployment provisions runtime service pods along with a dependency o ### SRS Version compatibility matrix -| Pega Infinity version | SRS version | Elasticsearch version | Description | -|-----------------------|-------------|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| < 8.6 | NA | NA | SRS can be used with Pega Infinity 8.6 and later | -| \>= 8.6 | 1.28.0 | 7.10.2, 7.16.3, and 7.17.9 | While SRS Docker images are certified against Elasticsearch versions 7.10.2, 7.16.3 and 7.17.9, Pega recommends using Elasticsearch version 7.17.9. To stay current with Pega releases, use the latest available SRS image 1.28.0. - -**Note**: - -**If your deployment uses the internally-provisioned Elasticsearch:** To migrate to Elasticsearch version 7.17.9 from the Elasticsearch version 7.10.2 or 7.16.3 use the process that applies to your deployment: - -* Update the SRS Docker image version to use v1.28.0, which supports both Elasticsearch versions 7.10.x and 7.16.x. -* Update the Elasticsearch `dependencies.version` parameter in the [requirement.yaml](../../requirements.yaml) to 7.17.3. -* Update Elasticsearch to 7.17.9. - -**If your deployment connects to an externally-managed Elasticsearch service:** To migrate to Elasticsearch version 7.17.9 from the Elasticsearch version 7.10.2 or 7.16.3 use the process that applies to your deployment: - -* Update the SRS Docker image version to use v1.28.0, which supports both Elasticsearch versions 7.10.x and 7.16.x. -* Complete the version upgrade to 7.17.9. Refer to Elasticsearch version 7.17 documentation. For example, see [Upgrade Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setup-upgrade.html). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pega Infinity versionSRS versionKubernetes versionAuthenticationCertified Elasticsearch versionDescription
< 8.6NANANANASRS can be used with Pega Infinity 8.6 and later
>= 8.6 1.29.1< 1.25No Authentication7.10.2, 7.16.3 & 7.17.9As a best practice, use Elasticsearch version 7.17.9.
Basic Authentication7.10.2, 7.16.3, 7.17.9 & 8.10.3As a best practice, use Elasticsearch version 8.10.3.
>= 1.25No Authentication7.16.3 & 7.17.9As a best practice, use Elasticsearch version 7.17.9.
Basic Authentication7.16.3, 7.17.9 & 8.10.3As a best practice, use Elasticsearch version 8.10.3.
+ +**Note:** + +### If your deployment uses the internally-provisioned Elasticsearch: ### +To migrate to Elasticsearch version 7.17.9 or 8.10.3 from the Elasticsearch version 7.10.2 or 7.16.3, perform the following steps: +1. Update the SRS Docker image version to use v1.29.1. This version has backward compatibility with Elasticsearch versions 7.10.x and 7.16.x, so your SRS will continue to work even before you update your Elasticsearch service. +2. To update Elasticsearch version to 7.17.9 perform the following actions: + * Update the Elasticsearch `dependencies.version` parameter in the [requirement.yaml](../../requirements.yaml) to 7.17.3. + + Note: This parameter references the Elasticsearch Helm chart version and not the Elasticsearch cluster version. + * Update the elasticsearch.imageTag in the Backing Services Helm chart to 7.17.9. +3. To update Elasticsearch version to 8.10.3, perform the following actions: + * Update the Elasticsearch `dependencies.version` parameter in the [requirement.yaml](../../requirements.yaml) to 8.5.1. + + Note: This parameter references the Elasticsearch Helm chart version and not the Elasticsearch cluster version. + * Update the elasticsearch.imageTag in the Backing Services Helm chart to 8.10.3. +4. Restart the SRS pods + +### If your deployment connects to an externally-managed Elasticsearch service: ### +To migrate to Elasticsearch version 7.17.9 or 8.10.3 from the Elasticsearch version 7.10.2 or 7.16.3, perform the following steps: +1. Update the SRS Docker image version to use v1.29.1. This version has backward compatibility with Elasticsearch versions 7.10.x and 7.16.x, so your SRS will continue to work even before you update your Elasticsearch service. +2. To use Elasticsearch version 7.17.9, upgrade your external Elasticsearch cluster to 7.17.9 according to your organization’s best practices. For more information, see official Elasticsearch version 7.17 documentation. +3. To use Elasticsearch version 8.10.3, upgrade your external Elasticsearch cluster to 8.10.3 according to your organization’s best practices. For more information, see official Elasticsearch version 8.10 documentation. +4. Restart the SRS pods ### SRS runtime configuration diff --git a/charts/backingservices/charts/srs/templates/_helpers.tpl b/charts/backingservices/charts/srs/templates/_helpers.tpl index f38f2e80f..b1336ccb3 100644 --- a/charts/backingservices/charts/srs/templates/_helpers.tpl +++ b/charts/backingservices/charts/srs/templates/_helpers.tpl @@ -166,11 +166,16 @@ app.kubernetes.io/instance: {{ .Release.Name }} {{- define "esDeploymentPassword" -}} {{- if and (.Values.srsStorage.tls.enabled) (not .Values.srsStorage.provisionInternalESCluster) (not .Values.srsStorage.basicAuthentication.enabled) (not .Values.srsStorage.awsIAM)}} -{{- .Values.srsStorage.esCredentials.password | b64enc }} +{{- .Values.srsStorage.esCredentials.password | b64enc }} {{- else if and (.Values.srsStorage.basicAuthentication.enabled) (not .Values.srsStorage.provisionInternalESCluster) (not .Values.srsStorage.tls.enabled) }} -{{- .Values.srsStorage.esCredentials.password | b64enc }} +{{- .Values.srsStorage.esCredentials.password | b64enc }} {{- else if and (.Values.srsStorage.provisionInternalESCluster) (not .Values.srsStorage.awsIAM) }} +{{- $secret := (lookup "v1" "Secret" .Release.Namespace "srs-elastic-credentials") }} +{{- if $secret }} +{{- index $secret.data "password" }} +{{- else}} {{- randAlphaNum 20 | b64enc}} +{{- end -}} {{- end}} {{- end}} diff --git a/charts/backingservices/values.yaml b/charts/backingservices/values.yaml index 861c4d396..977f5d5b3 100644 --- a/charts/backingservices/values.yaml +++ b/charts/backingservices/values.yaml @@ -18,7 +18,7 @@ srs: # Configure the location of the busybox image that is used during the deployment process of # the internal Elasticsearch cluster busybox: - image: "alpine:3.16.1" + image: "alpine:3.18.3" imagePullPolicy: "IfNotPresent" srsRuntime: @@ -86,8 +86,8 @@ constellation: # based on helm charts defined at https://github.com/elastic/helm-charts/tree/master/elasticsearch and may be modified # as per runtime and storage requirements. elasticsearch: - # For internally provisioned Elasticsearch server, the imageTag parameter is set by default to 7.17.9, which is the recommended Elasticsearch server version - # for k8s version >= 1.25. + # For internally provisioned Elasticsearch server, the imageTag parameter is set by default to 7.17.9, which is the + # recommended Elasticsearch server version for k8s version >= 1.25. # Use this parameter to change it to 7.10.2 or 7.16.3 for k8s version < 1.25 and make sure to update the Elasticsearch helm chart version in requirements.yaml. imageTag: 7.17.9 # Permit co-located instances for solitary minikube virtual machines. @@ -99,6 +99,12 @@ elasticsearch: # If you previously set srs.srsStorage.tls.enabled: true, you must uncomment the line to use protocol: https parameter. # protocol: https + # Uncomment the below lines if you want to deploy/upgrade Elasticsearch server version >= 8.x + # createCert: false + # secret: + # enabled: false + # protocol: http + # For deployments that use TLS-based authentication to an internal Elasticsearch service in the SRS cluster, # uncomment and appropriately add below lines under esConfig.elasticsearch.yml. # xpack.security.http.ssl.enabled: true @@ -107,11 +113,14 @@ elasticsearch: esConfig: elasticsearch.yml: | - xpack.security.enabled: true - xpack.security.transport.ssl.enabled: true - xpack.security.transport.ssl.verification_mode: certificate - xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 - xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 + xpack.security.enabled: true + xpack.security.transport.ssl.enabled: true + xpack.security.transport.ssl.verification_mode: certificate + xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 + xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 + # Uncomment the below lines if you want to deploy/upgrade Elasticsearch server version >= 8.x by adding below lines under esConfig.elasticsearch.yml. + # action.destructive_requires_name: false + # ingest.geoip.downloader.enabled: false # Use this section to include additional, supported environmental variables for Elasticsearch basic authentication. # The parameter values can be read from a specified secrets file. From b1bbcb187a8cb49dd1067bb4f6ebe10f4d25fd4e Mon Sep 17 00:00:00 2001 From: maracle6 <45719028+maracle6@users.noreply.github.com> Date: Fri, 2 Feb 2024 01:19:36 -0800 Subject: [PATCH 24/37] Document customerDeploymentId (#683) * Document customerDeploymentId * Document customerDeploymentId * Document customerDeploymentId * Lint fix --------- Co-authored-by: MadhuriArugula --- charts/pega/README.md | 2 ++ charts/pega/values-large.yaml | 3 +++ charts/pega/values-minimal.yaml | 3 +++ charts/pega/values.yaml | 3 +++ 4 files changed, 11 insertions(+) diff --git a/charts/pega/README.md b/charts/pega/README.md index 97e6762a5..ce806a231 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -810,6 +810,8 @@ Use the chart ['backingservices'](../backingservices) to deploy the Search and R To use SRS, follow the deployment instructions provided at ['backingservices'](../backingservices) before you configure and deploy the Pega Helm chart. For more information, see [External Elasticsearch in your deployment](https://docs.pega.com/bundle/platform-88/page/platform/deployment/externalization-of-services/externalize-search-in-your-deployment.html). +Configure the customerDeploymentId parameter in the global section of the values.yaml to provide data isolation in SRS. The customerDeploymentId is used as a prefix for all indexes created in ElasticSearch, and must be the value of the 'guid' claim if OAuth is used for authorization between Pega and SRS. This parameter defaults to the name of the namespace when left empty. + You must configure the SRS URL for your Pega Platform deployment using the parameter in values.yaml as shown the following table and example: Parameter | Description | Default value diff --git a/charts/pega/values-large.yaml b/charts/pega/values-large.yaml index 49dcddf82..595e6379b 100644 --- a/charts/pega/values-large.yaml +++ b/charts/pega/values-large.yaml @@ -7,6 +7,9 @@ global: # Enter your Kubernetes provider. provider: "YOUR_KUBERNETES_PROVIDER" + # Enter a name for the deployment if using multi-tenant services such as the Search and Reporting Service. + customerDeploymentId: + deployment: # The name specified will be used to prefix all of the Pega pods (replacing "pega" with something like "app1-dev"). name: "pega" diff --git a/charts/pega/values-minimal.yaml b/charts/pega/values-minimal.yaml index af6b8e50b..33523df76 100755 --- a/charts/pega/values-minimal.yaml +++ b/charts/pega/values-minimal.yaml @@ -7,6 +7,9 @@ global: # Enter your Kubernetes provider. provider: "k8s" + # Enter a name for the deployment if using multi-tenant services such as the Search and Reporting Service. + customerDeploymentId: + # Deploy Pega nodes actions: execute: "deploy" diff --git a/charts/pega/values.yaml b/charts/pega/values.yaml index 8c18c13b4..4d4e286cc 100644 --- a/charts/pega/values.yaml +++ b/charts/pega/values.yaml @@ -6,6 +6,9 @@ global: # Enter your Kubernetes provider. provider: "YOUR_KUBERNETES_PROVIDER" + # Enter a name for the deployment if using multi-tenant services such as the Search and Reporting Service. + customerDeploymentId: + deployment: # The name specified will be used to prefix all of the Pega pods (replacing "pega" with something like "app1-dev"). name: "pega" From 095b8422e09b120825e7d6f1d596ddf18ea7a842 Mon Sep 17 00:00:00 2001 From: Andrew Roskuski Date: Fri, 2 Feb 2024 17:48:50 -0500 Subject: [PATCH 25/37] make sure certificates defaults to dict (#697) * make sure certificates defaults to dict * try making test more specific * check for warning in test --- charts/pega/values.yaml | 2 +- ...oyment-with-and-without-customcert_test.go | 98 +++++++++---------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/charts/pega/values.yaml b/charts/pega/values.yaml index 4d4e286cc..1760fbb56 100644 --- a/charts/pega/values.yaml +++ b/charts/pega/values.yaml @@ -22,7 +22,7 @@ global: # to support multiple custom certificates as external secrets, specify each of your external secrets # as an array of comma-separated strings using the certificatesSecrets parameter. certificatesSecrets: [] - certificates: + certificates: {} # Add krb5.conf file content here. # Feature is used for Decisioning data flows to fetch data from Kafka or HBase streams diff --git a/terratest/src/test/pega/pega-tier-deployment-with-and-without-customcert_test.go b/terratest/src/test/pega/pega-tier-deployment-with-and-without-customcert_test.go index 8043ec55c..d11bc27b7 100644 --- a/terratest/src/test/pega/pega-tier-deployment-with-and-without-customcert_test.go +++ b/terratest/src/test/pega/pega-tier-deployment-with-and-without-customcert_test.go @@ -4,6 +4,7 @@ import ( "path/filepath" "strings" "testing" + "github.com/gruntwork-io/terratest/modules/helm" "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" @@ -20,68 +21,67 @@ func TestPegaDeploymentWithAndWithoutCustomCerts(t *testing.T) { for _, vendor := range supportedVendors { for _, operation := range supportedOperations { - var options = &helm.Options{ - ValuesFiles: []string{"data/values_with_customcerts.yaml"}, - SetValues: map[string]string{ - "global.deployment.name": "pega", - "global.provider": vendor, - "global.actions.execute": operation, - "installer.upgrade.upgradeType": "zero-downtime", - }, - } - deploymentYaml := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) - yamlSplit := strings.Split(deploymentYaml, "---") - assertWeb(t, yamlSplit[1], options) - assertVolumeAndMount(t, yamlSplit[1], options, true) - - assertBatch(t, yamlSplit[2], options) - assertVolumeAndMount(t, yamlSplit[2], options, true) - - assertStream(t, yamlSplit[3], options) - assertVolumeAndMount(t, yamlSplit[3], options, true) - - options.ValuesFiles = []string{"data/values_without_customcerts.yaml"} - - deploymentYaml = RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) - yamlSplit = strings.Split(deploymentYaml, "---") - assertWeb(t, yamlSplit[1], options) - assertVolumeAndMount(t, yamlSplit[1], options, false) - - assertBatch(t, yamlSplit[2], options) - assertVolumeAndMount(t, yamlSplit[2], options, false) - - assertStream(t, yamlSplit[3], options) - assertVolumeAndMount(t, yamlSplit[3], options, false) - } + var options = &helm.Options{ + ValuesFiles: []string{"data/values_with_customcerts.yaml"}, + SetValues: map[string]string{ + "global.deployment.name": "pega", + "global.provider": vendor, + "global.actions.execute": operation, + "installer.upgrade.upgradeType": "zero-downtime", + }, + } + renderTierForCertTest(t, options, helmChartPath, true) + + options.ValuesFiles = []string{"data/values_without_customcerts.yaml"} + + renderTierForCertTest(t, options, helmChartPath, false) + } } } +func renderTierForCertTest(t *testing.T, options *helm.Options, helmChartPath string, shouldHaveVol bool) { + + deploymentYaml := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) + + yamlSplit := strings.Split(deploymentYaml, "---") + assertWeb(t, yamlSplit[1], options) + assertVolumeAndMount(t, yamlSplit[1], options, shouldHaveVol) + + assertBatch(t, yamlSplit[2], options) + assertVolumeAndMount(t, yamlSplit[2], options, shouldHaveVol) + + assertStream(t, yamlSplit[3], options) + assertVolumeAndMount(t, yamlSplit[3], options, shouldHaveVol) + + require.False(t, strings.Contains(deploymentYaml, "Conflict: cannot merge map onto non-map"), "'cannot merge map onto non-map' warning should not be logged") +} + func assertVolumeAndMount(t *testing.T, tierYaml string, options *helm.Options, shouldHaveVol bool) { var deploymentObj appsv1.Deployment UnmarshalK8SYaml(t, tierYaml, &deploymentObj) pod := deploymentObj.Spec.Template.Spec - var foundVol = false + var foundVol = false for _, vol := range pod.Volumes { - if vol.Name == "pega-volume-import-certificates" { - foundVol = true - break - } + if vol.Name == "pega-volume-import-certificates" { + foundVol = true + break + } } require.Equal(t, shouldHaveVol, foundVol) - var foundVolMount = false + var foundVolMount = false for _, container := range pod.Containers { - if container.Name == "pega-web-tomcat" { - for _, volMount := range container.VolumeMounts { - if volMount.Name == "pega-volume-import-certificates" { - require.Equal(t, "/opt/pega/certs", volMount.MountPath) - foundVolMount = true - break - } - } - break - } + if container.Name == "pega-web-tomcat" { + for _, volMount := range container.VolumeMounts { + if volMount.Name == "pega-volume-import-certificates" { + require.Equal(t, "/opt/pega/certs", volMount.MountPath) + foundVolMount = true + break + } + } + break + } } require.Equal(t, shouldHaveVol, foundVolMount) From 105aea130facd804637995111c4695f35aad4bca Mon Sep 17 00:00:00 2001 From: punda1 <93995817+punda1@users.noreply.github.com> Date: Mon, 5 Feb 2024 18:55:14 +0530 Subject: [PATCH 26/37] Updated SRS Compatibility Matrix (#700) * TASK-1564442: Updating srs chart README to remove 7.16.3 support for K8s >=1.25, and minor changes related to authentication * TASK-1564442: Minor update * TASK-1564442: Addressing review comments --- charts/backingservices/charts/srs/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index 286660c01..1c6a8b0ba 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -33,30 +33,30 @@ The service deployment provisions runtime service pods along with a dependency o NA NA NA - SRS can be used with Pega Infinity 8.6 and later + SRS can be used with Pega Infinity 8.6 and later. >= 8.6 1.29.1 < 1.25 - No Authentication + Not enabled 7.10.2, 7.16.3 & 7.17.9 - As a best practice, use Elasticsearch version 7.17.9. + As a best practice, use Elasticsearch version 7.17.9. Deployments without authentication are not recommended for production environments. - Basic Authentication + Enabled 7.10.2, 7.16.3, 7.17.9 & 8.10.3 As a best practice, use Elasticsearch version 8.10.3. >= 1.25 - No Authentication - 7.16.3 & 7.17.9 - As a best practice, use Elasticsearch version 7.17.9. + Not enabled + 7.17.9 + As a best practice, use Elasticsearch version 7.17.9. Deployments without authentication are not recommended for production environments. - Basic Authentication - 7.16.3, 7.17.9 & 8.10.3 + Enabled + 7.17.9 & 8.10.3 As a best practice, use Elasticsearch version 8.10.3. From 36e377b5dda92ea0c970529367f4a14d77b41895 Mon Sep 17 00:00:00 2001 From: Divyansh Bhowmick <126799799+bhowd1@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:46:07 +0530 Subject: [PATCH 27/37] [SRS] Enabling secrets for ES certs and auth credentials (#696) * Enabling secrets for ES certs and credentials * Added secrets for basic-auth * Updated the docs * Fixed lint issues * Addresed review comments --- charts/backingservices/charts/srs/README.md | 9 +++++++++ .../srs/templates/elasticsearchsecret.yaml | 2 +- .../srs/templates/srsservice_deployment.yaml | 20 +++++++++++++------ charts/backingservices/values.yaml | 7 +++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/charts/backingservices/charts/srs/README.md b/charts/backingservices/charts/srs/README.md index 1c6a8b0ba..f8545577c 100644 --- a/charts/backingservices/charts/srs/README.md +++ b/charts/backingservices/charts/srs/README.md @@ -129,6 +129,8 @@ To configure a secure connection between SRS and an external Elasticsearch clust | `tls` | Set to `true` to enable the SRS service to authenticate to your organization's available Elasticsearch service. | | `certificateName` | Enter the tls certificate name. Default certificate name will be "elastic-certificates.p12" if not used. | | `certificatePassword` | Enter the tls certificate password if any. Default value will be empty if not used. | +| `certsSecret` | To specify a certificate using a secret, uncomment the certsSecret parameter and provide the secret name containing your certificate and certificate password. Use the full name of the certificate file (together with file extension, for example, “certificate.p12” or“certificate.jks”) as a key name in the secret. Use this key name to configure the “certificateName”parameter.Use a key name “password” to provide the certificate password in the secret. Defaults to "srs-certificates".| +| `authSecret` | Specify the secret with your Elasticsearch credentials. Use “username” and “password” as keys for your secret.This parameter applies to both basic authentication and TLS-based authentication. Defaults to "srs-elastic-credentials".| | `esCredentials.username` | Enter the username for your available Elasticsearch service. This username value must match the values you set in the connection info section of esCredentials. | | `esCredentials.password` | Enter the required password for your available Elasticsearch service. This password value must match the values you set in the connection info section of esCredentials. | | `srsStorage.provisionInternalESCluster` |
  1. Set the `srsStorage.provisionInternalESCluster` parameter to `false` to disable the internally provisioned Elasticsearch cluster and connect to your available external Elasticsearch service.
  2. To secure the connection between SRS and your external Elasticsearch service, you must provide the appropriate TLS certificates in an accessible location, for example, /home/certs.
  3. To pass the required certificates to the cluster using a secrets file, run the following command:

    `$ make external-es-secrets NAMESPACE= ELASTICSEARCH_VERSION= PATH_TO_CERTIFICATE=`

    Where NAMESPACE references your deployment namespace of the SRS cluster, `ELASTICSEARCH_VERSION` matches the Elasticsearch version you want to use, and `PATH_TO_CERTIFICATE` points to the location where you copied the required certificates on your location machine, for example:

    `$ make external-es-secrets NAMESPACE=pegabackingservices ELASTICSEARCH_VERSION=7.10.2 PATH_TO_CERTIFICATE=/home/certs/truststore.jks`

  4. To update the SRS and External Elasticsearch certificates, use the following command:

    `$ make update-external-es-secrets NAMESPACE= PATH_TO_CERTIFICATE=`

| @@ -197,6 +199,10 @@ srs: # Default certificatePassword value will be empty if not used. # certificateName: "Certificate_Name" # certificatePassword: "password" + # To specify a certificate using a secret, uncomment the certsSecret parameter and provide the secret name containing your certificate and certificate password. + # Use the full name of the certificate file (together with file extension, for example, “certificate.p12” or “certificate.jks”) as a key name in the secret. Use this key name to configure the “certificateName” parameter. + # Use a key name “password” to provide the certificate password in the secret. + # certsSecret: srs-certificates # Set srs.srsStorage.basicAuthentication.enabled: true to enable the use of basic authentication to your Elasticsearch service whether is it running as an internalized or externalized service in your SRS cluster. basicAuthentication: enabled: true @@ -204,6 +210,9 @@ srs: # esCredentials: # username: "username" # password: "password" + # To use a secret to configure basic authentication or TLS-based authentication between your external Elasticsearch service and SRS, + # uncomment the authSecret parameter and set it to the secret name. Use "username" and "password" as keys for your secret. + # authSecret: srs-elastic-credentials # To configure AWS IAM role-based authentication to your externally-managed Elasticsearch cluster, uncomment # and add the parameter details: srs.srsStorage.awsIAM and its associated region, srs.srsStorage.awsIAM.region # awsIAM: diff --git a/charts/backingservices/charts/srs/templates/elasticsearchsecret.yaml b/charts/backingservices/charts/srs/templates/elasticsearchsecret.yaml index 12fae0391..693478e8f 100644 --- a/charts/backingservices/charts/srs/templates/elasticsearchsecret.yaml +++ b/charts/backingservices/charts/srs/templates/elasticsearchsecret.yaml @@ -1,4 +1,4 @@ -{{- if or (eq (include "elasticsearch.authProvider" .) "basic-authentication") (eq (include "elasticsearch.authProvider" .) "tls")}} +{{- if and (not .Values.srsStorage.authSecret) (or (eq (include "elasticsearch.authProvider" .) "basic-authentication") (eq (include "elasticsearch.authProvider" .) "tls"))}} apiVersion: v1 kind: Secret metadata: diff --git a/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml b/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml index 3ff3af933..5bc225ca3 100644 --- a/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml +++ b/charts/backingservices/charts/srs/templates/srsservice_deployment.yaml @@ -60,30 +60,38 @@ spec: {{- if eq (include "elasticsearch.authProvider" $) "basic-authentication" }} - name: ELASTICSEARCH_USERNAME valueFrom: - secretKeyRef: - name: srs-elastic-credentials + secretKeyRef: + name: "{{ .Values.srsStorage.authSecret | default "srs-elastic-credentials"}}" key: username - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: - name: srs-elastic-credentials + name: "{{ .Values.srsStorage.authSecret | default "srs-elastic-credentials"}}" key: password {{- end}} {{- if eq (include "elasticsearch.authProvider" $) "tls" }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: - name: srs-elastic-credentials + name: "{{ .Values.srsStorage.authSecret | default "srs-elastic-credentials"}}" key: username - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: - name: srs-elastic-credentials + name: "{{ .Values.srsStorage.authSecret | default "srs-elastic-credentials"}}" key: password - name: PATH_TO_TRUSTSTORE value: "/usr/share/{{ .Values.srsStorage.certificateName | default "elastic-certificates.p12"}}" + {{ if not .Values.srsStorage.certsSecret }} - name: PATH_TO_KEYSTORE value: "{{ .Values.srsStorage.certificatePassword | default ""}}" + {{ else }} + - name: PATH_TO_KEYSTORE + valueFrom: + secretKeyRef: + name: "{{ .Values.srsStorage.certsSecret | default "srs-certificates"}}" + key: password + {{- end }} {{- end}} - name: APPLICATION_HOST value: "0.0.0.0" @@ -101,7 +109,7 @@ spec: volumes: - name: srs-certificates secret: - secretName: srs-certificates + secretName: "{{ .Values.srsStorage.certsSecret | default "srs-certificates"}}" {{ end }} {{- if .Values.srsStorage.provisionInternalESCluster }} initContainers: diff --git a/charts/backingservices/values.yaml b/charts/backingservices/values.yaml index 977f5d5b3..eab5c969c 100644 --- a/charts/backingservices/values.yaml +++ b/charts/backingservices/values.yaml @@ -61,6 +61,10 @@ srs: # Default certificatePassword value will be empty if not used. # certificateName: "Certificate_Name" # certificatePassword: "password" + # To specify a certificate using a secret, uncomment the certsSecret parameter and provide the secret name containing your certificate and certificate password. + # Use the full name of the certificate file (together with file extension, for example, “certificate.p12” or “certificate.jks”) as a key name in the secret. Use this key name + # to configure the “certificateName” parameter. Use a key name “password” to provide the certificate password in the secret. + # certsSecret: srs-certificates # Set srs.srsStorage.basicAuthentication.enabled: true to enable the use of basic authentication to your Elasticsearch service # whether is it running as an internalized or externalized service in your SRS cluster. basicAuthentication: @@ -70,6 +74,9 @@ srs: # esCredentials: # username: "username" # password: "password" + # To use a secret to configure basic authentication or TLS-based authentication between your external Elasticsearch service and SRS, + # uncomment the authSecret parameter and set it to the secret name. Use "username" and "password" as keys for your secret. + # authSecret: srs-elastic-credentials # To configure AWS IAM role-based authentication to your externally-managed Elasticsearch cluster, uncomment # and add the parameter details: srs.srsStorage.awsIAM and its associated region, srs.srsStorage.awsIAM.region # awsIAM: From 4b46c5041656ff29d9968c01f538838604eb1a98 Mon Sep 17 00:00:00 2001 From: chandraprakash kistaiahgari Date: Tue, 6 Feb 2024 17:25:15 +0530 Subject: [PATCH 28/37] US-393502 : pega-helm-chart version in repo should match build versions (#699) Chart version sync --- .github/workflows/github-actions-build.yml | 8 ++++ charts/addons/Chart.yaml | 2 +- charts/backingservices/Chart.yaml | 2 +- sync_chart_version.sh | 46 ++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 sync_chart_version.sh diff --git a/.github/workflows/github-actions-build.yml b/.github/workflows/github-actions-build.yml index 19e5598c5..59206e93b 100644 --- a/.github/workflows/github-actions-build.yml +++ b/.github/workflows/github-actions-build.yml @@ -191,5 +191,13 @@ jobs: cd $GITHUB_WORKSPACE chmod 777 update_gh_pages.sh ./update_gh_pages.sh + env: + GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_SECRET }} + + - name: sync chart version + run: | + cd $GITHUB_WORKSPACE + chmod 777 sync_chart_version.sh + ./sync_chart_version.sh env: GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_SECRET }} \ No newline at end of file diff --git a/charts/addons/Chart.yaml b/charts/addons/Chart.yaml index f72a0b21a..c4b74dec7 100644 --- a/charts/addons/Chart.yaml +++ b/charts/addons/Chart.yaml @@ -3,4 +3,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: addons -version: 1.2.0 +version: "1.2.0" diff --git a/charts/backingservices/Chart.yaml b/charts/backingservices/Chart.yaml index 7d812fe68..9f3f9c4db 100644 --- a/charts/backingservices/Chart.yaml +++ b/charts/backingservices/Chart.yaml @@ -17,4 +17,4 @@ description: Helm Chart to provision the latest Search and Reporting Service (SR # The chart version: Pega provides this as a useful way to track changes you make to this chart. # As a best practice, you should increment the version number each time you make changes to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.2.0 +version: "1.2.0" diff --git a/sync_chart_version.sh b/sync_chart_version.sh new file mode 100644 index 000000000..3da109dd9 --- /dev/null +++ b/sync_chart_version.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e +tagVersion="" +if [ ${GITHUB_REF_TYPE} == "tag" ] +then + tagVersion=${GITHUB_REF_NAME} +fi +export CHART_VERSION=$(expr ${tagVersion:1}) + +echo "${GITHUB_REF}" +echo "${GITHUB_REPOSITORY}" +echo "${GITHUB_ACTOR}" + +repo_uri="https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" +remote_name="origin" +target_branch="master" +tmp_build_dir="/tmp/build_dir" + +cd "$GITHUB_WORKSPACE" + +git config --global user.name "$GITHUB_ACTOR" +git config --global user.email "${GITHUB_ACTOR}@bots.github.com" + +echo "Creating a temporary directory to build" +mkdir -p "$tmp_build_dir" + +echo "clone a single branch master" +git clone --quiet --branch="$target_branch" --depth=1 "$repo_uri" "$tmp_build_dir" > /dev/null + +cd "$tmp_build_dir" + +# Update version in charts/pega/Chart.yaml +awk -v new_version="${CHART_VERSION}" '/^version:/ {$2="\"" new_version "\""}1' charts/pega/Chart.yaml > temp && mv temp charts/pega/Chart.yaml +# Update version in charts/addons/Chart.yaml +awk -v new_version="${CHART_VERSION}" '/^version:/ {$2="\"" new_version "\""}1' charts/addons/Chart.yaml > temp && mv temp charts/addons/Chart.yaml +# Update version in charts/backingservices/Chart.yaml +awk -v new_version="${CHART_VERSION}" '/^version:/ {$2="\"" new_version "\""}1' charts/backingservices/Chart.yaml > temp && mv temp charts/backingservices/Chart.yaml + +# Commit changes +git add charts/pega/Chart.yaml charts/addons/Chart.yaml charts/backingservices/Chart.yaml + +echo "Updating chart versions to ${CHART_VERSION}" +git commit -m "Update chart versions to ${CHART_VERSION}" + +echo "Pushing to master" +git push -q "$remote_name" "$target_branch" > /dev/null \ No newline at end of file From db04440e262919b716f86f86a7009e0582611e57 Mon Sep 17 00:00:00 2001 From: vnihal72 <79415342+vnihal72@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:46:38 +0530 Subject: [PATCH 29/37] BUG-851649 : Pod distribution budget added to clustering service (#695) Co-authored-by: vermn1 --- .../templates/clustering-service-pdb.yaml | 20 +++++++++++++++++++ .../hazelcast/templates/pega-hz-pdb.yaml | 20 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 charts/pega/charts/hazelcast/templates/clustering-service-pdb.yaml create mode 100644 charts/pega/charts/hazelcast/templates/pega-hz-pdb.yaml diff --git a/charts/pega/charts/hazelcast/templates/clustering-service-pdb.yaml b/charts/pega/charts/hazelcast/templates/clustering-service-pdb.yaml new file mode 100644 index 000000000..91026135b --- /dev/null +++ b/charts/pega/charts/hazelcast/templates/clustering-service-pdb.yaml @@ -0,0 +1,20 @@ +{{ if and (eq (include "performDeployment" .) "true") (eq (include "isClusteringServiceEnabled" .) "true") }} + {{- if (semverCompare ">= 1.21.0-0" (trimPrefix "v" .Capabilities.KubeVersion.GitVersion)) }} +apiVersion: policy/v1 + {{- else }} +apiVersion: policy/v1beta1 + {{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "clusteringServiceName" . }}-pdb + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "clusteringServiceName" . }} + component: Hazelcast +spec: + maxUnavailable: 1 + selector: + matchLabels: + app: {{ template "clusteringServiceName" . }} + component: Hazelcast +{{- end }} \ No newline at end of file diff --git a/charts/pega/charts/hazelcast/templates/pega-hz-pdb.yaml b/charts/pega/charts/hazelcast/templates/pega-hz-pdb.yaml new file mode 100644 index 000000000..99251d488 --- /dev/null +++ b/charts/pega/charts/hazelcast/templates/pega-hz-pdb.yaml @@ -0,0 +1,20 @@ +{{ if and (eq (include "performDeployment" .) "true") (eq (include "isHazelcastEnabled" .) "true") }} + {{- if (semverCompare ">= 1.21.0-0" (trimPrefix "v" .Capabilities.KubeVersion.GitVersion)) }} +apiVersion: policy/v1 + {{- else }} +apiVersion: policy/v1beta1 + {{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "hazelcastName" . }}-pdb + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "hazelcastName" . }} + component: Hazelcast +spec: + maxUnavailable: 1 + selector: + matchLabels: + app: {{ template "hazelcastName" . }} + component: Hazelcast +{{- end }} \ No newline at end of file From 26c7665534bc3bdaf4ccb8605cce4fc6d6b523a1 Mon Sep 17 00:00:00 2001 From: chandraprakash kistaiahgari Date: Tue, 6 Feb 2024 18:40:27 +0530 Subject: [PATCH 30/37] US-393502: resolving chart version update tmp directory creation (#701) chart version sync --- sync_chart_version.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/sync_chart_version.sh b/sync_chart_version.sh index 3da109dd9..4c3997f10 100644 --- a/sync_chart_version.sh +++ b/sync_chart_version.sh @@ -22,6 +22,7 @@ git config --global user.name "$GITHUB_ACTOR" git config --global user.email "${GITHUB_ACTOR}@bots.github.com" echo "Creating a temporary directory to build" +rm -rf "$tmp_build_dir" mkdir -p "$tmp_build_dir" echo "clone a single branch master" From 151a7be0afa7b0b7fd026855aaa2b95f9a28ce3d Mon Sep 17 00:00:00 2001 From: Saurabh-16 Date: Tue, 6 Feb 2024 13:17:58 +0000 Subject: [PATCH 31/37] Update chart versions to 3.15.1 --- charts/addons/Chart.yaml | 2 +- charts/backingservices/Chart.yaml | 2 +- charts/pega/Chart.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/addons/Chart.yaml b/charts/addons/Chart.yaml index c4b74dec7..42d1ae5f7 100644 --- a/charts/addons/Chart.yaml +++ b/charts/addons/Chart.yaml @@ -3,4 +3,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: addons -version: "1.2.0" +version: "3.15.1" diff --git a/charts/backingservices/Chart.yaml b/charts/backingservices/Chart.yaml index 9f3f9c4db..e479306d6 100644 --- a/charts/backingservices/Chart.yaml +++ b/charts/backingservices/Chart.yaml @@ -17,4 +17,4 @@ description: Helm Chart to provision the latest Search and Reporting Service (SR # The chart version: Pega provides this as a useful way to track changes you make to this chart. # As a best practice, you should increment the version number each time you make changes to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: "1.2.0" +version: "3.15.1" diff --git a/charts/pega/Chart.yaml b/charts/pega/Chart.yaml index 1d4022417..65de172fd 100644 --- a/charts/pega/Chart.yaml +++ b/charts/pega/Chart.yaml @@ -1,7 +1,7 @@ --- apiVersion: v1 name: pega -version: "1.2.0" +version: "3.15.1" description: Pega installation on kubernetes keywords: - pega From 96cbb8792031d5093495eb0e0e5dd0622ed4ef3b Mon Sep 17 00:00:00 2001 From: Andrew Roskuski Date: Tue, 6 Feb 2024 16:36:42 -0500 Subject: [PATCH 32/37] update software used in build (#703) * update software used in build * update test for newer k8s * update test for new k8s * add version notes --- .github/workflows/github-actions-build.yml | 16 ++++++++-------- terratest/src/test/pega/pega-tier-pdb_test.go | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/github-actions-build.yml b/.github/workflows/github-actions-build.yml index 59206e93b..64bb19ea0 100644 --- a/.github/workflows/github-actions-build.yml +++ b/.github/workflows/github-actions-build.yml @@ -2,9 +2,9 @@ name: Pega Chart Build env: HELM_URL: https://get.helm.sh - HELM_TGZ: helm-v3.6.3-linux-amd64.tar.gz - YAMLLINT_VERSION: 1.15.0 - GO_VERSION: 1.18.3 + HELM_TGZ: helm-v3.11.3-linux-amd64.tar.gz + YAMLLINT_VERSION: 1.34.0 + GO_VERSION: 1.21.6 on: @@ -23,7 +23,7 @@ concurrency: jobs: run-supplemental-validation-job: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Check out repository code uses: actions/checkout@v3 @@ -31,7 +31,7 @@ jobs: run : | sh validate_supplementals.sh run-lint-job: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Check out repository code uses: actions/checkout@v3 @@ -72,7 +72,7 @@ jobs: sh validatexml.sh run-remark-job: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Check out repository code uses: actions/checkout@v3 @@ -91,7 +91,7 @@ jobs: remark -i .remark_ignore -f -u validate-links . run-go-tests-job: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Check out repository code uses: actions/checkout@v3 @@ -144,7 +144,7 @@ jobs: go test ./backingservices | grep "FAIL" -A 8 || true ; test ${PIPESTATUS[0]} -eq 0 run-deploy-job: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: [run-lint-job, run-remark-job, run-go-tests-job] if: ( github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v') ) && success() steps: diff --git a/terratest/src/test/pega/pega-tier-pdb_test.go b/terratest/src/test/pega/pega-tier-pdb_test.go index 0997267ce..3b25f4cee 100644 --- a/terratest/src/test/pega/pega-tier-pdb_test.go +++ b/terratest/src/test/pega/pega-tier-pdb_test.go @@ -11,6 +11,10 @@ import ( "k8s.io/api/policy/v1beta1" ) +// Leaving the k8s.io import at v1beta1 for now because it doesn't impact the test and upgrading seems like it would probably require going +// through all the Go dependencies. If this test starts failing in the future due to new features not being supported, we should probably +// actually go through and do the upgrade + // TestPegaTierPDBEnabled - verify that a PodDisruptionBudget is created when global.tier.pdb.enabled=true func TestPegaTierPDBEnabled(t *testing.T) { var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} @@ -44,19 +48,19 @@ func TestPegaTierPDBEnabled(t *testing.T) { { name: getObjName(options, "-web-pdb"), kind: "PodDisruptionBudget", - apiversion: "policy/v1beta1", + apiversion: "policy/v1", minAvailable: 1, }, { name: getObjName(options, "-batch-pdb"), kind: "PodDisruptionBudget", - apiversion: "policy/v1beta1", + apiversion: "policy/v1", minAvailable: 1, }, { name: getObjName(options, "-stream-pdb"), kind: "PodDisruptionBudget", - apiversion: "policy/v1beta1", + apiversion: "policy/v1", minAvailable: 1, }, }) @@ -100,21 +104,21 @@ func TestPegaTierPDBWithCustomLabels(t *testing.T) { { name: getObjName(options, "-web-pdb"), kind: "PodDisruptionBudget", - apiversion: "policy/v1beta1", + apiversion: "policy/v1", labels: webPDBLabels, minAvailable: 1, }, { name: getObjName(options, "-batch-pdb"), kind: "PodDisruptionBudget", - apiversion: "policy/v1beta1", + apiversion: "policy/v1", labels: batchPDBLabels, minAvailable: 1, }, { name: getObjName(options, "-stream-pdb"), kind: "PodDisruptionBudget", - apiversion: "policy/v1beta1", + apiversion: "policy/v1", minAvailable: 1, }, }) @@ -175,8 +179,6 @@ func verifyPegaPDBs(t *testing.T, yamlContent string, options *helm.Options, exp // verifyPegaPdb - Performs Pega PDB assertions with the values as provided func verifyPegaPdb(t *testing.T, pegaPdbObj *v1beta1.PodDisruptionBudget, expectedPdb pdb) { require.Equal(t, pegaPdbObj.TypeMeta.Kind, expectedPdb.kind) - //if the below fails it means that the helm version used in testing is compiled against - //kubernetes 1.21 or higher, and we should adjust this test to use the policy/v1 API version require.Equal(t, pegaPdbObj.TypeMeta.APIVersion, expectedPdb.apiversion) require.Equal(t, expectedPdb.minAvailable, pegaPdbObj.Spec.MinAvailable.IntVal) From 328022074c49ac2e2915f4fb2f7cc8efc5193a88 Mon Sep 17 00:00:00 2001 From: Davis Walsh Date: Fri, 16 Feb 2024 15:20:42 -0500 Subject: [PATCH 33/37] fix usage appender in prlog4j2.xml (#707) --- charts/pega/config/deploy/prlog4j2.xml | 8 ++++---- .../src/test/pega/data/expectedInstallDeployPRlog4j2.xml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/charts/pega/config/deploy/prlog4j2.xml b/charts/pega/config/deploy/prlog4j2.xml index 860959a77..0ab532ce0 100644 --- a/charts/pega/config/deploy/prlog4j2.xml +++ b/charts/pega/config/deploy/prlog4j2.xml @@ -110,15 +110,15 @@ - + %m%n - - + + - + diff --git a/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml b/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml index c1910278b..e54f0169b 100644 --- a/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml +++ b/terratest/src/test/pega/data/expectedInstallDeployPRlog4j2.xml @@ -110,15 +110,15 @@ - + %m%n - - + + - + From 31d2214362f707741ba6f567c3ff79deca973d64 Mon Sep 17 00:00:00 2001 From: APegaDavis Date: Fri, 16 Feb 2024 20:26:31 +0000 Subject: [PATCH 34/37] Update chart versions to 3.15.2 --- charts/addons/Chart.yaml | 2 +- charts/backingservices/Chart.yaml | 2 +- charts/pega/Chart.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/addons/Chart.yaml b/charts/addons/Chart.yaml index 42d1ae5f7..011ee57df 100644 --- a/charts/addons/Chart.yaml +++ b/charts/addons/Chart.yaml @@ -3,4 +3,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: addons -version: "3.15.1" +version: "3.15.2" diff --git a/charts/backingservices/Chart.yaml b/charts/backingservices/Chart.yaml index e479306d6..8381055c5 100644 --- a/charts/backingservices/Chart.yaml +++ b/charts/backingservices/Chart.yaml @@ -17,4 +17,4 @@ description: Helm Chart to provision the latest Search and Reporting Service (SR # The chart version: Pega provides this as a useful way to track changes you make to this chart. # As a best practice, you should increment the version number each time you make changes to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: "3.15.1" +version: "3.15.2" diff --git a/charts/pega/Chart.yaml b/charts/pega/Chart.yaml index 65de172fd..33c800bda 100644 --- a/charts/pega/Chart.yaml +++ b/charts/pega/Chart.yaml @@ -1,7 +1,7 @@ --- apiVersion: v1 name: pega -version: "3.15.1" +version: "3.15.2" description: Pega installation on kubernetes keywords: - pega From 8c960b9184c2872eebe446bea086f560dbffe6af Mon Sep 17 00:00:00 2001 From: Uma Veera Date: Thu, 22 Feb 2024 10:38:38 +0530 Subject: [PATCH 35/37] US-598110: Provide stabilization window feature to hpa during scaling to avoid flapping issue (#708) * US-598110: Provide stabilizationWindowSeconds feature during scaling to avoid flapping issue(github issue - 676) * US-598110: Provide stabilizationWindowSeconds feature during scaling to avoid flapping issue(github issue - 676) * fixed formatting issues * fixed formatting issues --------- Co-authored-by: rajuu --- charts/pega/README.md | 9 ++ charts/pega/templates/_pega_hpa.tpl | 6 +- charts/pega/values-large.yaml | 5 ++ charts/pega/values.yaml | 5 ++ .../test/pega/data/values_hpa_behavior.yaml | 17 ++++ terratest/src/test/pega/pega-tier-hpa_test.go | 82 ++++++++++++++++--- 6 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 terratest/src/test/pega/data/values_hpa_behavior.yaml diff --git a/charts/pega/README.md b/charts/pega/README.md index ce806a231..3406b1bfc 100644 --- a/charts/pega/README.md +++ b/charts/pega/README.md @@ -1307,3 +1307,12 @@ tls: insecureSkipVerify: true ``` + +```yaml +# To enable HorizontalPodAutoscaler behavior specifications, configure the following settings against each tier: +behavior: + scaleDown: + stabilizationWindowSeconds: << provide scaleDown stabilization window in seconds >> + scaleUp: + stabilizationWindowSeconds: << provide scaleUp stabilization window in seconds >> +``` \ No newline at end of file diff --git a/charts/pega/templates/_pega_hpa.tpl b/charts/pega/templates/_pega_hpa.tpl index 7bf84bca6..47b268150 100644 --- a/charts/pega/templates/_pega_hpa.tpl +++ b/charts/pega/templates/_pega_hpa.tpl @@ -28,7 +28,7 @@ spec: maxReplicas: {{ .hpa.maxReplicas }} {{- else }} maxReplicas: 5 - {{- end }} + {{- end }} metrics: {{- if (hasKey .hpa "enableCpuTarget" | ternary .hpa.enableCpuTarget true) }} - type: Resource @@ -58,6 +58,10 @@ spec: averageUtilization: 85 {{- end }} {{- end }} + {{- if .hpa.behavior}} + behavior: +{{ toYaml .hpa.behavior | indent 4 }} + {{- end }} --- {{- end -}} diff --git a/charts/pega/values-large.yaml b/charts/pega/values-large.yaml index 595e6379b..63d1fa9a1 100644 --- a/charts/pega/values-large.yaml +++ b/charts/pega/values-large.yaml @@ -216,6 +216,11 @@ global: hpa: enabled: true + # To configure behavior specifications for hpa, set the required scaleUp & scaleDown values. + # See, https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#stabilization-window + # behavior: + # scaleDown: + # stabilizationWindowSeconds: 600 # Set enabled to true to include a Pod Disruption Budget for this tier. # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable diff --git a/charts/pega/values.yaml b/charts/pega/values.yaml index 1760fbb56..e8c70ef3e 100644 --- a/charts/pega/values.yaml +++ b/charts/pega/values.yaml @@ -247,6 +247,11 @@ global: hpa: enabled: true + # To configure behavior specifications for hpa, set the required scaleUp & scaleDown values. + # See, https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#stabilization-window + # behavior: + # scaleDown: + # stabilizationWindowSeconds: 600 # Set enabled to true to include a Pod Disruption Budget for this tier. # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable diff --git a/terratest/src/test/pega/data/values_hpa_behavior.yaml b/terratest/src/test/pega/data/values_hpa_behavior.yaml new file mode 100644 index 000000000..3d767bf7a --- /dev/null +++ b/terratest/src/test/pega/data/values_hpa_behavior.yaml @@ -0,0 +1,17 @@ +--- +global: + tier: + - name: "web" + hpa: + enabled: true + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + scaleUp: + stabilizationWindowSeconds: 0 + - name: "batch" + hpa: + enabled: true + behavior: + scaleDown: + stabilizationWindowSeconds: 200 diff --git a/terratest/src/test/pega/pega-tier-hpa_test.go b/terratest/src/test/pega/pega-tier-hpa_test.go index 9e4facd75..cb4ec1eb2 100644 --- a/terratest/src/test/pega/pega-tier-hpa_test.go +++ b/terratest/src/test/pega/pega-tier-hpa_test.go @@ -222,6 +222,61 @@ func TestPegaTierOverrideValues(t *testing.T) { } } +func TestPegaTierHPAWithBehavior(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + + testsPath, err := filepath.Abs(PegaHelmChartTestsPath) + require.NoError(t, err) + + for _, vendor := range supportedVendors { + + for _, operation := range supportedOperations { + + for _, depName := range deploymentNames { + fmt.Println(vendor + "-" + operation + "-" + depName) + + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "installer.upgrade.upgradeType": "zero-downtime", + }, + } + + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-hpa.yaml"}, "--values", testsPath+"/data/values_hpa_behavior.yaml") + verifyPegaHPAs(t, yamlContent, options, []hpa{ + { + name: getObjName(options, "-web-hpa"), + targetRefName: getObjName(options, "-web"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + behavior: true, + scaleDownStabilizationWindow: 300, + scaleUpStabilizationWindow: 0, + }, + { + name: getObjName(options, "-batch-hpa"), + targetRefName: getObjName(options, "-batch"), + kind: "Deployment", + apiversion: "apps/v1", + cpu: true, + cpuValue: parseResourceValue(t, "2.55"), + behavior: true, + scaleDownStabilizationWindow: 200, + }, + }) + } + } + } +} + // verifyPegaHPAs - Splits the HPA object from the rendered template and asserts each HPA object func verifyPegaHPAs(t *testing.T, yamlContent string, options *helm.Options, expectedHpas []hpa) { var pegaHpaObj autoscaling.HorizontalPodAutoscaler @@ -270,20 +325,27 @@ func verifyPegaHpa(t *testing.T, hpaObj *autoscaling.HorizontalPodAutoscaler, ex require.Equal(t, expectedValue, actual) } + if expectedHpa.behavior { + require.Equal(t, *hpaObj.Spec.Behavior.ScaleDown.StabilizationWindowSeconds, expectedHpa.scaleDownStabilizationWindow) + require.Equal(t, *hpaObj.Spec.Behavior.ScaleUp.StabilizationWindowSeconds, expectedHpa.scaleUpStabilizationWindow) + } require.Equal(t, int32(5), hpaObj.Spec.MaxReplicas) } type hpa struct { - name string - targetRefName string - kind string - apiversion string - labels map[string]string - cpu bool - cpuValue resource.Quantity - cpuPercent int32 - mem bool - memPercent int32 + name string + targetRefName string + kind string + apiversion string + labels map[string]string + cpu bool + cpuValue resource.Quantity + cpuPercent int32 + mem bool + memPercent int32 + behavior bool + scaleDownStabilizationWindow int32 + scaleUpStabilizationWindow int32 } func (h hpa) expectedMetricCount() int { From 969b6e96310403d81d34d710ddb5ed94aa793d54 Mon Sep 17 00:00:00 2001 From: PEGA-NarasimhaRao-Meda <109585795+PEGA-NarasimhaRao-Meda@users.noreply.github.com> Date: Thu, 22 Feb 2024 11:11:42 +0530 Subject: [PATCH 36/37] US-598183: Support for Topology Spread Constraints (#709) * US-598183: Add Support for topology spread constraints * US-598183: Addressed the indention errors * US-598183: Fixed comment indention errors * US-598183: Removed topology constraint configuration from values-minimal --------- Co-authored-by: MadhuriArugula --- .../templates/pega-search-deployment.yaml | 7 + charts/pega/charts/pegasearch/values.yaml | 11 ++ charts/pega/templates/_pega-deployment.tpl | 4 + charts/pega/values-large.yaml | 12 ++ charts/pega/values.yaml | 12 ++ ...oyment-topology-spread-constraints_test.go | 182 ++++++++++++++++++ 6 files changed, 228 insertions(+) create mode 100644 terratest/src/test/pega/pega-deployment-topology-spread-constraints_test.go diff --git a/charts/pega/charts/pegasearch/templates/pega-search-deployment.yaml b/charts/pega/charts/pegasearch/templates/pega-search-deployment.yaml index 7522ad89d..389bff149 100644 --- a/charts/pega/charts/pegasearch/templates/pega-search-deployment.yaml +++ b/charts/pega/charts/pegasearch/templates/pega-search-deployment.yaml @@ -24,6 +24,9 @@ spec: labels: app: {{ template "searchName" . }} component: "Search" +{{- if .Values.podLabels }} +{{ toYaml .Values.podLabels | indent 8 }} +{{- end }} {{- if .Values.podAnnotations }} annotations: {{ toYaml .Values.podAnnotations | indent 8 }} @@ -54,6 +57,10 @@ spec: securityContext: privileged: true {{ end }} +{{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.topologySpreadConstraints | indent 8 }} +{{- end }} containers: - name: search image: {{ .Values.image }} diff --git a/charts/pega/charts/pegasearch/values.yaml b/charts/pega/charts/pegasearch/values.yaml index a9c10bbfc..ad2bb8a8c 100644 --- a/charts/pega/charts/pegasearch/values.yaml +++ b/charts/pega/charts/pegasearch/values.yaml @@ -37,3 +37,14 @@ set_data_owner_on_startup: false # Additional custom fields, such as environment variables custom: env: [] + +# Key-Value pairs that are attached to the pods (https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) +# podLabels: + +# Topology spread constraints to control the placement of your pods across nodes, zones, regions, or other user-defined topology domains. +# For more information please refer https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ +# topologySpreadConstraints: +# - maxSkew: +# topologyKey: +# whenUnsatisfiable: +# labelSelector: diff --git a/charts/pega/templates/_pega-deployment.tpl b/charts/pega/templates/_pega-deployment.tpl index 0db586531..d04bd17e8 100644 --- a/charts/pega/templates/_pega-deployment.tpl +++ b/charts/pega/templates/_pega-deployment.tpl @@ -129,6 +129,10 @@ spec: runAsUser: 9001 fsGroup: 0 {{- end }} +{{- end }} +{{- if .node.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .node.topologySpreadConstraints | indent 8 }} {{- end }} containers: # Name of the container diff --git a/charts/pega/values-large.yaml b/charts/pega/values-large.yaml index 63d1fa9a1..f4f9e3f45 100644 --- a/charts/pega/values-large.yaml +++ b/charts/pega/values-large.yaml @@ -222,6 +222,18 @@ global: # scaleDown: # stabilizationWindowSeconds: 600 + # key/value pairs that are attached to the pods (https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) + # podLabels: + + # Topology spread constraints to control the placement of your pods across nodes, zones, regions, or other user-defined topology domains. + # For more information please refer https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ + # If you want to apply topology spread constraints in other tiers, please use the same configuration as described here. + # topologySpreadConstraints: + # - maxSkew: + # topologyKey: + # whenUnsatisfiable: + # labelSelector: + # Set enabled to true to include a Pod Disruption Budget for this tier. # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable # value and comment out the other parameter. diff --git a/charts/pega/values.yaml b/charts/pega/values.yaml index e8c70ef3e..6f58bebcd 100644 --- a/charts/pega/values.yaml +++ b/charts/pega/values.yaml @@ -253,6 +253,18 @@ global: # scaleDown: # stabilizationWindowSeconds: 600 + # key/value pairs that are attached to the pods (https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) + # podLabels: + + # Topology spread constraints to control the placement of your pods across nodes, zones, regions, or other user-defined topology domains. + # For more information please refer https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ + # If you want to apply topology spread constraints in other tiers, please use the same configuration as described here. + # topologySpreadConstraints: + # - maxSkew: + # topologyKey: + # whenUnsatisfiable: + # labelSelector: + # Set enabled to true to include a Pod Disruption Budget for this tier. # To enable this budget, specifiy either a pdb.minAvailable or pdb.maxUnavailable # value and comment out the other parameter. diff --git a/terratest/src/test/pega/pega-deployment-topology-spread-constraints_test.go b/terratest/src/test/pega/pega-deployment-topology-spread-constraints_test.go new file mode 100644 index 000000000..9fd352cd0 --- /dev/null +++ b/terratest/src/test/pega/pega-deployment-topology-spread-constraints_test.go @@ -0,0 +1,182 @@ +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 TestPegaTierDeploymentWithMultiTopologySpreadConstraints(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + var depObj appsv1.Deployment + for _, vendor := range supportedVendors { + for _, operation := range supportedOperations { + for _, deploymentName := range deploymentNames { + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "global.deployment.name": deploymentName, + "installer.upgrade.upgradeType": "zero-downtime", + "global.tier[0].name": "web", + "global.tier[0].topologySpreadConstraints[0].maxSkew": "1", + "global.tier[0].topologySpreadConstraints[0].topologyKey": "zone", + "global.tier[0].topologySpreadConstraints[0].whenUnsatisfiable": "DoNotSchedule", + "global.tier[0].topologySpreadConstraints[0].labelSelector.matchLabels.key": "web-pod", + "global.tier[0].topologySpreadConstraints[1].maxSkew": "2", + "global.tier[0].topologySpreadConstraints[1].topologyKey": "node", + "global.tier[0].topologySpreadConstraints[1].whenUnsatisfiable": "ScheduleAnyway", + "global.tier[0].topologySpreadConstraints[1].labelSelector.matchLabels.key": "web-pod2", + }, + } + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) + yamlSplit := strings.Split(yamlContent, "---") + UnmarshalK8SYaml(t, yamlSplit[1], &depObj) + constraints := depObj.Spec.Template.Spec.TopologySpreadConstraints + require.Equal(t, "zone", constraints[0].TopologyKey) + require.Equal(t, 1, int(constraints[0].MaxSkew)) + require.Equal(t, "DoNotSchedule", string(constraints[0].WhenUnsatisfiable)) + require.Equal(t, "web-pod", constraints[0].LabelSelector.MatchLabels["key"]) + require.Equal(t, "node", constraints[1].TopologyKey) + require.Equal(t, 2, int(constraints[1].MaxSkew)) + require.Equal(t, "ScheduleAnyway", string(constraints[1].WhenUnsatisfiable)) + require.Equal(t, "web-pod2", constraints[1].LabelSelector.MatchLabels["key"]) + } + } + } +} + +func TestPegaTierDeploymentWithSingleTopologySpreadConstraints(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + var depObj appsv1.Deployment + for _, vendor := range supportedVendors { + for _, operation := range supportedOperations { + for _, deploymentName := range deploymentNames { + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "global.deployment.name": deploymentName, + "installer.upgrade.upgradeType": "zero-downtime", + "global.tier[0].name": "web", + "global.tier[0].topologySpreadConstraints[0].maxSkew": "2", + "global.tier[0].topologySpreadConstraints[0].topologyKey": "zoneName", + "global.tier[0].topologySpreadConstraints[0].whenUnsatisfiable": "ScheduleAnyway", + "global.tier[0].topologySpreadConstraints[0].labelSelector.matchLabels.app": "web-pod", + }, + } + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) + yamlSplit := strings.Split(yamlContent, "---") + UnmarshalK8SYaml(t, yamlSplit[1], &depObj) + constraints := depObj.Spec.Template.Spec.TopologySpreadConstraints + require.Equal(t, "zoneName", constraints[0].TopologyKey) + require.Equal(t, 2, int(constraints[0].MaxSkew)) + require.Equal(t, "ScheduleAnyway", string(constraints[0].WhenUnsatisfiable)) + require.Equal(t, "web-pod", constraints[0].LabelSelector.MatchLabels["app"]) + } + } + } +} + +func TestPegaTierDeploymentWithoutTopologySpreadConstraints(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + var depObj appsv1.Deployment + for _, vendor := range supportedVendors { + for _, operation := range supportedOperations { + for _, deploymentName := range deploymentNames { + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "global.deployment.name": deploymentName, + "installer.upgrade.upgradeType": "zero-downtime", + "global.tier[0].name": "web", + }, + } + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"}) + yamlSplit := strings.Split(yamlContent, "---") + UnmarshalK8SYaml(t, yamlSplit[1], &depObj) + constraints := depObj.Spec.Template.Spec.TopologySpreadConstraints + require.Empty(t, constraints) + } + } + } +} + +func TestPegaSearchDeploymentWithTopologySpreadConstraints(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + var depObj appsv1.Deployment + for _, vendor := range supportedVendors { + for _, operation := range supportedOperations { + for _, deploymentName := range deploymentNames { + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "global.deployment.name": deploymentName, + "installer.upgrade.upgradeType": "zero-downtime", + "pegasearch.replicas": "2", + "pegasearch.topologySpreadConstraints[0].maxSkew": "2", + "pegasearch.topologySpreadConstraints[0].topologyKey": "az-name", + "pegasearch.topologySpreadConstraints[0].whenUnsatisfiable": "ScheduleAnyway", + }, + } + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"charts/pegasearch/templates/pega-search-deployment.yaml"}) + yamlSplit := strings.Split(yamlContent, "---") + UnmarshalK8SYaml(t, yamlSplit[1], &depObj) + constraints := depObj.Spec.Template.Spec.TopologySpreadConstraints + require.Equal(t, "az-name", constraints[0].TopologyKey) + require.Equal(t, 2, int(constraints[0].MaxSkew)) + require.Equal(t, "ScheduleAnyway", string(constraints[0].WhenUnsatisfiable)) + } + } + } +} + +func TestPegaSearchDeploymentWithoutTopologySpreadConstraints(t *testing.T) { + var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"} + var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"} + var deploymentNames = []string{"pega", "myapp-dev"} + helmChartPath, err := filepath.Abs(PegaHelmChartPath) + require.NoError(t, err) + var depObj appsv1.Deployment + for _, vendor := range supportedVendors { + for _, operation := range supportedOperations { + for _, deploymentName := range deploymentNames { + var options = &helm.Options{ + SetValues: map[string]string{ + "global.provider": vendor, + "global.actions.execute": operation, + "global.deployment.name": deploymentName, + "installer.upgrade.upgradeType": "zero-downtime", + "pegasearch.replicas": "2", + }, + } + yamlContent := RenderTemplate(t, options, helmChartPath, []string{"charts/pegasearch/templates/pega-search-deployment.yaml"}) + yamlSplit := strings.Split(yamlContent, "---") + UnmarshalK8SYaml(t, yamlSplit[1], &depObj) + constraints := depObj.Spec.Template.Spec.TopologySpreadConstraints + require.Empty(t, constraints) + } + } + } +} From e164935dd072f1a50a089cfd56200f75b5fe673c Mon Sep 17 00:00:00 2001 From: MadhuriArugula Date: Thu, 22 Feb 2024 15:08:06 +0530 Subject: [PATCH 37/37] US-558964 Update documentation links (#706) Co-authored-by: arugm --- docs/Deploying-Pega-on-EKS.md | 2 +- docs/resources/addons-eks.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Deploying-Pega-on-EKS.md b/docs/Deploying-Pega-on-EKS.md index e9cb6777d..5043ed882 100644 --- a/docs/Deploying-Pega-on-EKS.md +++ b/docs/Deploying-Pega-on-EKS.md @@ -454,7 +454,7 @@ To configure the use of an Amazon AWS ALB ingress controller in the addons.yaml - Uncomment and specify the Amazon EKS Amazon ECR image repository in the `image.repository`: parameter. This is required for AWS GovCloud deployments - Specify the complete required annotation to the role that you associate with the primary IAM user who is responsible for your EKS deployment in the `serviceAccount.annotations.eks.amazonaws.com/role-arn: ` parameter. -To ensure logging for your deployment is properly configured to take advantage of the built-in EFK logging tools in EKS deployments, refer to the [Amazon EKS Workshop](https://eksworkshop.com/logging/). +To ensure logging for your deployment is properly configured to take advantage of the built-in EFK logging tools in EKS deployments, refer to the [Amazon EKS Workshop](https://www.eksworkshop.com/docs/observability/logging/). #### Updating the backingservices.yaml Helm chart values for the SRS (Supported when installing or upgrading to Pega Infinity 8.6 and later) diff --git a/docs/resources/addons-eks.yaml b/docs/resources/addons-eks.yaml index fbeb8d25f..fb26ef3b3 100644 --- a/docs/resources/addons-eks.yaml +++ b/docs/resources/addons-eks.yaml @@ -9,7 +9,7 @@ aws-load-balancer-controller: region: "YOUR_EKS_CLUSTER_REGION" ## VPC ID of k8s cluster, required if ec2metadata is unavailable from controller pod. vpcId: "YOUR_EKS_CLUSTER_VPC_ID" - ## To create IAM Role, see https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html#create-service-account-iam-role + ## To create IAM Role, see https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html ## Create policy with https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json ## and attach it to the role. See, https://github.com/aws/eks-charts/tree/master/stable/aws-load-balancer-controller for more details serviceAccount: