From 86ed6dadda151afc76c14a3ee5a75b46dcfe7282 Mon Sep 17 00:00:00 2001 From: jonathan langlois Date: Thu, 27 Jun 2024 16:32:02 -0700 Subject: [PATCH] chore: ms graph change from bceid to ms graph --- docker/kc-cron-job/.env.example | 17 +- docker/kc-cron-job/package.json | 2 + .../kc-cron-job/remove-inactive-idir-users.js | 199 +++++++++--------- docker/kc-cron-job/yarn.lock | 82 ++++++++ helm/kc-cron-job/README.md | 5 - .../templates/cron-remove-inactive-users.yaml | 44 +++- helm/kc-cron-job/values-c6af30-tools.yaml | 72 +++++++ 7 files changed, 296 insertions(+), 125 deletions(-) create mode 100644 helm/kc-cron-job/values-c6af30-tools.yaml diff --git a/docker/kc-cron-job/.env.example b/docker/kc-cron-job/.env.example index 917e6d96..37288e37 100644 --- a/docker/kc-cron-job/.env.example +++ b/docker/kc-cron-job/.env.example @@ -1,8 +1,3 @@ -BCEID_SERVICE_BASIC_AUTH= -BCEID_REQUESTER_IDIR_GUID= -BCEID_SERVICE_ID_DEV= -BCEID_SERVICE_ID_TEST= -BCEID_SERVICE_ID_PROD= DEV_KEYCLOAK_CLIENT_ID= DEV_KEYCLOAK_CLIENT_SECRET= DEV_KEYCLOAK_URL=https://dev.loginproxy.gov.bc.ca @@ -23,3 +18,15 @@ RC_WEBHOOK= VC_USERS_RETENTION_DAYS= INACTIVE_IDIR_USERS_RETENTION_DAYS= NAMESPACE= + +MS_GRAPH_API_AUTHORITY_DEV= +MS_GRAPH_API_CLIENT_ID_DEV= +MS_GRAPH_API_CLIENT_SECRET_DEV= + +MS_GRAPH_API_AUTHORITY_TEST= +MS_GRAPH_API_CLIENT_ID_TEST= +MS_GRAPH_API_CLIENT_SECRET_TEST= + +MS_GRAPH_API_AUTHORITY_PROD= +MS_GRAPH_API_CLIENT_ID_PROD= +MS_GRAPH_API_CLIENT_SECRET_PROD= diff --git a/docker/kc-cron-job/package.json b/docker/kc-cron-job/package.json index 315b94ce..a16cded2 100644 --- a/docker/kc-cron-job/package.json +++ b/docker/kc-cron-job/package.json @@ -9,10 +9,12 @@ "test": "jest" }, "dependencies": { + "@azure/msal-node": "^2.9.2", "archiver": "^5.3.0", "async": "^3.2.4", "axios": "^1.4.0", "easy-soap-request": "^5.3.0", + "jsonwebtoken": "^9.0.2", "jws": "^4.0.0", "keycloak-admin": "^1.14.22", "lodash": "^4.17.21", diff --git a/docker/kc-cron-job/remove-inactive-idir-users.js b/docker/kc-cron-job/remove-inactive-idir-users.js index 3b8c0ac2..b0f949b7 100644 --- a/docker/kc-cron-job/remove-inactive-idir-users.js +++ b/docker/kc-cron-job/remove-inactive-idir-users.js @@ -1,126 +1,111 @@ const _ = require('lodash'); -const { promisify } = require('util'); -const { parseString } = require('xml2js'); const async = require('async'); const axios = require('axios'); const { getAdminClient, log, getPgClient, sendRcNotification, handleError, deleteLegacyData } = require('./helpers'); +const jwt = require('jsonwebtoken'); +const { ConfidentialClientApplication } = require('@azure/msal-node'); -require('dotenv').config(); - -const parseStringSync = promisify(parseString); - -function getWebServiceInfo({ env = 'dev' }) { - const requestHeaders = { - 'Content-Type': 'text/xml;charset=UTF-8', - authorization: `Basic ${process.env.BCEID_SERVICE_BASIC_AUTH}` - }; +const MS_GRAPH_URL = 'https://graph.microsoft.com'; +const MS_GRAPH_IDIR_GUID_ATTRIBUTE = 'onPremisesExtensionAttributes/extensionAttribute12'; - const requesterIdirGuid = process.env.BCEID_REQUESTER_IDIR_GUID || ''; +require('dotenv').config(); - let serviceUrl = ''; - let serviceId = ''; - if (env === 'dev') { - serviceUrl = 'https://gws2.development.bceid.ca'; - serviceId = process.env.BCEID_SERVICE_ID_DEV || ''; - } else if (env === 'test') { - serviceUrl = 'https://gws2.test.bceid.ca'; - serviceId = process.env.BCEID_SERVICE_ID_TEST || ''; - } else if (env === 'prod') { - serviceUrl = 'https://gws2.bceid.ca'; - serviceId = process.env.BCEID_SERVICE_ID_PROD || ''; - } +let devMsalInstance; +let testMsalInstance; +let prodMsalInstance; - return { requestHeaders, requesterIdirGuid, serviceUrl, serviceId }; -} - -const generateXML = ( - { - property = 'userId', - matchKey = '', - matchType = 'Exact', - serviceId = '', - requesterIdirGuid = '', - page = 1, - limit = 1 +let msTokenCache = { + dev: { + token: '', + decoded: null + }, + test: { + token: '', + decoded: null }, - requestType = 'searchInternalAccount' -) => { - if (requestType === 'getAccountDetail') { - return ` - - - - - - ${serviceId} - Internal - ${requesterIdirGuid} - ${matchKey} - Internal - - - - `; - } else { - return ` - - - - - - ${serviceId} - Internal - ${requesterIdirGuid} - Internal - - ${String(limit || 100)} - ${String(page || 1)} - - - Ascending - UserId - - - - ${matchKey} - ${matchType} - - - - - -`; + prod: { + token: '', + decoded: null } }; -async function checkUserExistsAtIDIM({ property = 'userGuid', matchKey = '', env = 'prod' }) { - const { requestHeaders, requesterIdirGuid, serviceUrl, serviceId } = getWebServiceInfo({ env }); - const xml = generateXML({ property, matchKey, serviceId, requesterIdirGuid }, 'getAccountDetail'); - +async function getAzureAccessToken(env) { try { - const response = await axios.post(`${serviceUrl}/webservices/client/V10/BCeIDService.asmx?WSDL`, xml, { - headers: requestHeaders, - timeout: 10000 - }); + const currentTime = Math.floor(Date.now() / 1000); + if (msTokenCache[env].decoded && msTokenCache[env].decoded?.exp > currentTime) { + return msTokenCache[env].token; + } + const request = { + scopes: [`${MS_GRAPH_URL}/.default`] + }; - const { data: body } = response; + let msalInstance; + switch (env) { + case 'dev': + msalInstance = + devMsalInstance || + new ConfidentialClientApplication({ + auth: { + authority: process.env.MS_GRAPH_API_AUTHORITY_DEV || '', + clientId: process.env.MS_GRAPH_API_CLIENT_ID_DEV || '', + clientSecret: process.env.MS_GRAPH_API_CLIENT_SECRET_DEV || '' + } + }); + break; + case 'test': + msalInstance = + testMsalInstance || + new ConfidentialClientApplication({ + auth: { + authority: process.env.MS_GRAPH_API_AUTHORITY_TEST || '', + clientId: process.env.MS_GRAPH_API_CLIENT_ID_TEST || '', + clientSecret: process.env.MS_GRAPH_API_CLIENT_SECRET_TEST || '' + } + }); + break; + case 'prod': + msalInstance = + prodMsalInstance || + new ConfidentialClientApplication({ + auth: { + authority: process.env.MS_GRAPH_API_AUTHORITY_PROD || '', + clientId: process.env.MS_GRAPH_API_CLIENT_ID_PROD || '', + clientSecret: process.env.MS_GRAPH_API_CLIENT_SECRET_PROD || '' + } + }); + break; + } + const response = await msalInstance.acquireTokenByClientCredential(request); + msTokenCache[env].token = response.accessToken; + msTokenCache[env].decoded = jwt.decode(response.accessToken); + return response.accessToken; + } catch (error) { + console.error(error); + throw new Error('Error acquiring access token'); + } +} - const result = await parseStringSync(body); - const data = _.get(result, 'soap:Envelope.soap:Body.0.getAccountDetailResponse.0.getAccountDetailResult.0'); - if (!data) throw Error('no data'); +async function checkUserExistsAtIDIM({ property = MS_GRAPH_IDIR_GUID_ATTRIBUTE, matchKey = '', env }) { + try { + const accessToken = await getAzureAccessToken(env); + const options = { + headers: { + Authorization: `Bearer ${accessToken}`, + ConsistencyLevel: 'eventual' + } + }; - const status = _.get(data, 'code.0'); - const failureCode = _.get(data, 'failureCode.0'); - const failMessage = _.get(data, 'message.0'); - if (status === 'Success' && failureCode === 'Void') { - return 'exists'; - } else if (status === 'Failed' && failureCode === 'NoResults') { + const url = `${MS_GRAPH_URL}/v1.0/users?$filter=${property} eq '${matchKey}'&$count=true`; + const result = await axios.get(url, options); + if (result && result.data?.value?.length === 0) { return 'notexists'; - } else { - log(`${env}: [${status}][${failureCode}] ${property}: ${matchKey}: ${String(failMessage)})`); } - return 'error'; + if (result && result.data?.value?.length > 0) { + return 'exists'; + } + throw new Error('unexpected response from ms graph'); } catch (error) { + console.log(error?.response?.data || error); throw new Error(error); } } @@ -195,7 +180,11 @@ async function removeStaleUsersByEnv(env = 'dev', pgClient, runnerName, startFro if (displayName && displayName.startsWith('hold -')) continue; log(`[${runnerName}] processing user ${username}`); if (username.includes('@idir')) { - const userExistsAtWb = await checkUserExistsAtIDIM({ property: 'userGuid', matchKey: idirUserGuid, env }); + const userExistsAtWb = await checkUserExistsAtIDIM({ + property: MS_GRAPH_IDIR_GUID_ATTRIBUTE, + matchKey: idirUserGuid, + env + }); if (userExistsAtWb === 'notexists') { const { realmRoles, clientRoles } = await getUserRolesMappings(adminClient, id); await removeUserFromKc(adminClient, id); diff --git a/docker/kc-cron-job/yarn.lock b/docker/kc-cron-job/yarn.lock index a38e5a0e..d50446de 100644 --- a/docker/kc-cron-job/yarn.lock +++ b/docker/kc-cron-job/yarn.lock @@ -15,6 +15,20 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@azure/msal-common@14.12.0": + version "14.12.0" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.12.0.tgz#844abe269b071f8fa8949dadc2a7b65bbb147588" + integrity sha512-IDDXmzfdwmDkv4SSmMEyAniJf6fDu3FJ7ncOjlxkDuT85uSnLEhZi3fGZpoR7T4XZpOMx9teM9GXBgrfJgyeBw== + +"@azure/msal-node@^2.9.2": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-2.9.2.tgz#e6d3c1661012c1bd0ef68e328f73a2fdede52931" + integrity sha512-8tvi6Cos3m+0KmRbPjgkySXi+UQU/QiuVRFnrxIwt5xZlEEFa69O04RTaNESGgImyBBlYbo2mfE8/U8Bbdk1WQ== + dependencies: + "@azure/msal-common" "14.12.0" + jsonwebtoken "^9.0.0" + uuid "^8.3.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13": version "7.22.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" @@ -2816,6 +2830,31 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +jsonwebtoken@^9.0.0, jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + jwa@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" @@ -2825,6 +2864,14 @@ jwa@^2.0.0: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + jws@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" @@ -2920,16 +2967,46 @@ lodash.flatten@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.union@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" @@ -3961,6 +4038,11 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-to-istanbul@^9.0.1: version "9.1.3" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" diff --git a/helm/kc-cron-job/README.md b/helm/kc-cron-job/README.md index 6bc79e31..b2e852c5 100644 --- a/helm/kc-cron-job/README.md +++ b/helm/kc-cron-job/README.md @@ -14,11 +14,6 @@ The deployment steps for a new namespace follow: ```sh # update rest of the values -export BCEID_SERVICE_BASIC_AUTH= -export BCEID_REQUESTER_IDIR_GUID= -export BCEID_SERVICE_ID_DEV= -export BCEID_SERVICE_ID_TEST= -export BCEID_SERVICE_ID_PROD= export DEV_KEYCLOAK_CLIENT_ID= export DEV_KEYCLOAK_CLIENT_SECRET= export DEV_KEYCLOAK_URL=https://dev.loginproxy.gov.bc.ca diff --git a/helm/kc-cron-job/templates/cron-remove-inactive-users.yaml b/helm/kc-cron-job/templates/cron-remove-inactive-users.yaml index d58d10b3..7a04c8b8 100644 --- a/helm/kc-cron-job/templates/cron-remove-inactive-users.yaml +++ b/helm/kc-cron-job/templates/cron-remove-inactive-users.yaml @@ -128,31 +128,55 @@ spec: secretKeyRef: name: kc-cron-job-secret key: prod-kc-password - - name: BCEID_SERVICE_BASIC_AUTH + + - name: MS_GRAPH_API_AUTHORITY_DEV valueFrom: secretKeyRef: name: kc-cron-job-secret - key: bceid-service-basic-auth - - name: BCEID_REQUESTER_IDIR_GUID + key: ms-graph-api-authority-dev + - name: MS_GRAPH_API_CLIENT_ID_DEV valueFrom: secretKeyRef: name: kc-cron-job-secret - key: bceid-requester-idir-guid - - name: BCEID_SERVICE_ID_DEV + key: ms-graph-api-client-id-dev + - name: MS_GRAPH_API_CLIENT_SECRET_DEV valueFrom: secretKeyRef: name: kc-cron-job-secret - key: bceid-service-id-dev - - name: BCEID_SERVICE_ID_TEST + key: ms-graph-api-client-secret-dev + + - name: MS_GRAPH_API_AUTHORITY_TEST valueFrom: secretKeyRef: name: kc-cron-job-secret - key: bceid-service-id-test - - name: BCEID_SERVICE_ID_PROD + key: ms-graph-api-authority-test + - name: MS_GRAPH_API_CLIENT_ID_TEST valueFrom: secretKeyRef: name: kc-cron-job-secret - key: bceid-service-id-prod + key: ms-graph-api-client-id-test + - name: MS_GRAPH_API_CLIENT_SECRET_TEST + valueFrom: + secretKeyRef: + name: kc-cron-job-secret + key: ms-graph-api-client-secret-test + + - name: MS_GRAPH_API_AUTHORITY_PROD + valueFrom: + secretKeyRef: + name: kc-cron-job-secret + key: ms-graph-api-authority-prod + - name: MS_GRAPH_API_CLIENT_ID_PROD + valueFrom: + secretKeyRef: + name: kc-cron-job-secret + key: ms-graph-api-client-id-prod + - name: MS_GRAPH_API_CLIENT_SECRET_PROD + valueFrom: + secretKeyRef: + name: kc-cron-job-secret + key: ms-graph-api-client-secret-prod + - name: CSS_API_URL valueFrom: secretKeyRef: diff --git a/helm/kc-cron-job/values-c6af30-tools.yaml b/helm/kc-cron-job/values-c6af30-tools.yaml new file mode 100644 index 00000000..858c65de --- /dev/null +++ b/helm/kc-cron-job/values-c6af30-tools.yaml @@ -0,0 +1,72 @@ +image: + repository: ghcr.io/bcgov/kc-cron-job + tag: dev + pullPolicy: Always + +imagePullSecrets: + - name: gh-registry-config + +nameOverride: kc-cron-job +fullnameOverride: kc-cron-job + +enableEventLogsJob: true + +enableActiveSessionsJob: false + +enableRemoveInactiveUsersJob: false + +enableRemoveVcUsersJob: false + +namespace: + eventLogs: + - 'c6af30-dev' + activeSessions: 'c6af30-tools' + rmInactiveUsers: 'c6af30-tools' + rmVcUsers: 'c6af30-tools' + +pvc: + name: sso-keycloak-logs + +networkPolicy: + environment: tools + licensePlate: c6af30 + +pgHost: kc-cron-patroni.c6af30-tools.svc.cluster.local + +resources: + limits: + cpu: 0.5 + memory: 512M + requests: + cpu: 0.25 + memory: 256M + +patroni: + nameOverride: kc-cron-patroni + fullnameOverride: kc-cron-patroni + replicaCount: 2 + resources: + requests: + cpu: 100m + memory: 400Mi + limits: + cpu: 200m + memory: 600Mi + ## Only uncoment on a first install + # credentials: + # existingSecret: false + # admin: + # username: admin + # password: + # standby: + # username: standby + # password: + # superuser: + # username: postgres + # password: + + additionalCredentials: + - username: rhsso + password: + +rocketChatWebhook: